数字谜题 Java解答

160 阅读1分钟

数字谜题 Java解答

搜索了一番,发现没有Java版的题解,就动手写了一个,应该没什么问题。 为节约时间,有了答案就return了,需要全部答案,可修改 return resultCount + "=" + dpString.get(i);为 System.out.println(resultCount + "=" + dpString.get(i));

public class count {
    public static void main(String[] args) throws Exception {
        int resultCount = 99;
        Object[] nums = {7,7,7,8,8,8,8,9,9,9};
        Object[] operators = {"+","+","*","-","-"};
        int result = nums.length-operators.length;
        if (result<1){
            throw new Exception("传入的参数有误,请检查参数");
        }
        List<Object> operatorList = new ArrayList<>();
        for (int i = 0; i < result-1; i++) {
            operatorList.add("&");
        }
        operatorList.addAll(Arrays.asList(operators));
        operators = operatorList.toArray();
        System.out.println("==============题目===============");
        System.out.println(nums.toString());
        System.out.println(operators.toString());
        System.out.println(resultCount);
        System.out.println("==============解答===============");
        List<List<Object>> numberSortList = permuteUnique(nums);
        List<List<Object>> operatorSortList = permuteUnique(operators);
        System.out.println(expression(numberSortList, operatorSortList, resultCount));
    }

    public static String expression(List<List<Object>> numberSortList,List<List<Object>> operatorSortList,int resultCount){
        for (List<Object> numberList : numberSortList) {
            for (List<Object> opList : operatorSortList) {
                StringBuilder builder = new StringBuilder();
                builder.append(numberList.get(0));
                for (int i = 0; i < numberList.size() - 1; i++) {
                    builder.append(opList.get(i));
                    builder.append(numberList.get(i + 1));
                }
                String s = builder.toString();
                Map<String, Object> map = diffWaysToCompute(s);
                List<Long> dp = (List<Long>) map.get("dp");
                List<String> dpString = (List<String>) map.get("dpString");
                for (int i = 0; i < dp.size(); i++) {
                    if (dp.get(i) == resultCount) {
                        return resultCount + "=" + dpString.get(i);
                    }
                }
            }
        }
        return "传入的参数有误,请检查参数";
    }

    private static boolean[] vis;

    public static List<List<Object>> permuteUnique(Object[] nums) {
        List<List<Object>> ans = new ArrayList<List<Object>>();
        List<Object> perm = new ArrayList<Object>();
        vis = new boolean[nums.length];
        Arrays.sort(nums);
        backtrack(nums, ans, 0, perm);
        return ans;
    }

    public static void backtrack(Object[] nums, List<List<Object>> ans, int idx, List<Object> perm) {
        if (idx == nums.length) {
            ans.add(new ArrayList<Object>(perm));
            return;
        }
        for (int i = 0; i < nums.length; ++i) {
            if (vis[i] || (i > 0 && nums[i] == nums[i - 1] && !vis[i - 1])) {
                continue;
            }
            perm.add(nums[i]);
            vis[i] = true;
            backtrack(nums, ans, idx + 1, perm);
            vis[i] = false;
            perm.remove(idx);
        }
    }

    static final long ADDITION = -1;
    static final long SUBTRACTION = -2;
    static final long MULTIPLICATION = -3;
    static final long DIVISION= -4;
    static final long AND = -5;

    public static Map<String,Object> diffWaysToCompute(String expression) {
        List<Long> ops = new ArrayList<Long>();
        for (int i = 0; i < expression.length();) {
            if (!Character.isDigit(expression.charAt(i))) {
                if (expression.charAt(i) == '+') {
                    ops.add(ADDITION);
                } else if (expression.charAt(i) == '-') {
                    ops.add(SUBTRACTION);
                } else if(expression.charAt(i) == '*'){
                    ops.add(MULTIPLICATION);
                } else if(expression.charAt(i) == '/'){
                    ops.add(DIVISION);
                } else if(expression.charAt(i) == '&'){
                    ops.add(AND);
                }
                i++;
            } else {
                long t = 0;
                while (i < expression.length() && Character.isDigit(expression.charAt(i))) {
                    t = t * 10 + expression.charAt(i) - '0';
                    i++;
                }
                ops.add(t);
            }
        }
        List<Long>[][] dp = new List[ops.size()][ops.size()];
        List<String>[][] dpString = new List[ops.size()][ops.size()];
        for (int i = 0; i < ops.size(); i++) {
            for (int j = 0; j < ops.size(); j++) {
                dp[i][j] = new ArrayList<Long>();
                dpString[i][j] = new ArrayList<String>();
            }
        }
        for (int i = 0; i < ops.size(); i += 2) {
            dp[i][i].add(ops.get(i));
            dpString[i][i].add(ops.get(i).toString());
        }
        for (int i = 3; i <= ops.size(); i++) {
            for (int j = 0; j + i <= ops.size(); j += 2) {
                int l = j;
                int r = j + i - 1;
                for (int k = j + 1; k < r; k += 2) {
                    List<Long> left = dp[l][k - 1];
                    List<String> leftString = dpString[l][k - 1];
                    List<Long> right = dp[k + 1][r];
                    List<String> rightString = dpString[k + 1][r];
                    for (int i1 = 0; i1 < left.size(); i1++) {
                        for (int i2 = 0; i2 < right.size(); i2++) {
                            if (ops.get(k) == ADDITION) {
                                if (left.get(i1)==-6||right.get(i2)==-6){
                                    dp[l][r].add(-6L);
                                    dpString[l][r].add("error");
                                }else {
                                    dp[l][r].add(left.get(i1) + right.get(i2));
                                    dpString[l][r].add("("+leftString.get(i1)+"+"+ rightString.get(i2)+")");
                                }
                            } else if (ops.get(k) == SUBTRACTION) {
                                if (left.get(i1)==-6||right.get(i2)==-6){
                                    dp[l][r].add(-6L);
                                    dpString[l][r].add("error");
                                }else {
                                    long temp = left.get(i1) - right.get(i2);
                                    if(temp<0){
                                        dp[l][r].add(-6L);
                                        dpString[l][r].add("error");
                                    }else {
                                        dp[l][r].add(temp);
                                        dpString[l][r].add("("+leftString.get(i1)+"-"+ rightString.get(i2)+")");
                                    }
                                }
                            } else if (ops.get(k) == MULTIPLICATION) {
                                if (left.get(i1)==-6||right.get(i2)==-6){
                                    dp[l][r].add(-6L);
                                    dpString[l][r].add("error");
                                }else {
                                    dp[l][r].add(left.get(i1) * right.get(i2));
                                    dpString[l][r].add("("+leftString.get(i1)+"*"+ rightString.get(i2)+")");
                                }
                            } else if (ops.get(k) == DIVISION) {
                                if (left.get(i1)==-6||right.get(i2)==-6){
                                    dp[l][r].add(-6L);
                                    dpString[l][r].add("error");
                                }else {
                                    if (right.get(i2)==0||left.get(i1) % right.get(i2)!=0){
                                        dp[l][r].add(-6L);
                                        dpString[l][r].add("error");
                                    }else {
                                        dp[l][r].add(left.get(i1) / right.get(i2));
                                        dpString[l][r].add("("+leftString.get(i1)+"/"+ rightString.get(i2)+")");
                                    }
                                }
                            } else if (ops.get(k) == AND) {
                                if (left.get(i1)==-6||right.get(i2)==-6){
                                    dp[l][r].add(-6L);
                                    dpString[l][r].add("error");
                                }else {
                                    dp[l][r].add(Long.parseLong(left.get(i1).toString()  + right.get(i2).toString()));
                                    dpString[l][r].add("("+leftString.get(i1)+"&"+ rightString.get(i2)+")");
                                }
                            }
                        }
                    }
                }
            }
        }
        Map<String,Object> map = new HashMap();
        map.put("dp",dp[0][ops.size() - 1]);
        map.put("dpString",dpString[0][ops.size() - 1]);
        return map;
    }
}