算法设计与分析: 5-18 无优先级运算问题

5-18 无优先级运算问题


问题描述

给定 n 个正整数和 4 个运算符+、-、*、/,且运算符无优先级,如 2+3*5=25。对于任意给定的整数 m,试设计一个算法,用以上给出的 n 个数和 4 个运算符,产生整数 m, 且用的运算次数最少。给出的 n 个数中每个数最多只能用 1 次,但每种运算符可以任意使用。

对于给定的 n 个正整数,设计一个算法,用最少的无优先级运算次数产生整数 m。

数据输入:
第一行有 2 个正整数 n 和 m。第 2 行是给定的用于运算的 n 个正整数。


Java

package Chapter5HuiSuFa;

import java.util.Scanner;

public class WuYouXianJiYunSuan {

    private static int n,m,k;
    private static int[] a,num,oper;
    private static boolean[] used;

    public static void main(String[] args){
        Scanner input = new Scanner(System.in);

        while (true){
            n = input.nextInt();
            m = input.nextInt();

            a = new int[n];
            num = new int[n];
            oper = new int[n];
            used = new boolean[n];

            for(int i=0; i<n; i++){
                a[i] = input.nextInt();
                used[i] = false;
            }

            for(k=0; k<n; k++){
                if(search(0)){
                    System.out.println(k);
                    out();
                    return;
                }
            }

            System.out.println("No Solution!");
        }
    }

    private static boolean search(int dep){
        if(dep > k){
            if(found()) return true;
            else return false;
        }
        for(int i=0; i<n; i++)
            if(!used[i]){
                num[dep] = a[i];
                used[i] = true;
                for(int j=0; j<4; j++){
                    oper[dep] = j;
                    if(search(dep+1))
                        return true;
                }
                used[i] = false;
            }

        return false;
    }

    private static boolean found(){
        int x = num[0];
        for(int i=0; i<k; i++){
            switch (oper[i]){
                case 0: x += num[i+1]; break;
                case 1: x -= num[i+1]; break;
                case 2: x *= num[i+1]; break;
                case 3: x /= num[i+1]; break;
            }
        }

        return (x==m);
    }

    private static void out(){
        System.out.print(num[0]);
        for(int i=0; i<k; i++)
            switch (oper[i]){
                case 0: System.out.print("+"+num[i+1]); continue;
                case 1: System.out.print("-"+num[i+1]); continue;
                case 2: System.out.print("*"+num[i+1]); continue;
                case 3: System.out.print("/"+num[i+1]); continue;
            }
    }
}

Input & Output

5 25
5 2 3 6 7
2
2+3*5

Reference

王晓东《计算机算法设计与分析》(第3版)P185

猜你喜欢

转载自blog.csdn.net/ioio_/article/details/81129616