【24点】java减治法实现二十四点,输出所有求值结果为24的组合

题目要求:

用户输入4位个位数(1~9),四个数之间只能通过+,-,*,/运算进行连接
请输出四则运算表达式,其求值结果为24。然后输出所有求值结果为24的组合。
你能不能不通过四重循环来产生这4个参与运算的数。

代码如下:

package ergodic;

import java.util.*;
/**
 * @ Author     :heywecome
 * @ Date       :Created in 20:32 2018/12/20
 * @ Description:${description}
 * @ Modified By:
 * @Version: $version$
 */
public class TwentyFour {
    // 用户输入4位个位数(1~9),四个数之间只能通过+,-,*,/运算进行连接,请输出四则运算表达式,
    // 其求值结果为24。然后输出所有求值结果为24的组合。你能不能不通过四重循环来产生这4个参与运算的数。
    static final String PLUS = "+";
    static final String DIVIDE = "-";
    static final String MULTIPLY= "*";
    static final String SUBSTRACT = "/";
    static ArrayList resultList = new ArrayList();
    static ArrayList operatorList = new ArrayList();

    static String[] operator = {PLUS,DIVIDE,MULTIPLY,SUBSTRACT}; // 操作符的排列

    public static void findAllSolution(int[] nums){
        perm(nums,0,nums.length-1); // 产生数的排列

        perm(operator,0,operator.length-1);

        for(int i = 0; i < nums.length; i++){ // 四个数产生不同的排列
            for(int j = 0; j < operatorList.size(); j++){
                String formula = new String();
                int[] numsTemp = (int[]) resultList.get(i);

                String[] operatorTemp = (String[])operatorList.get(j);
                // 加括号的第一种情况: (a+b)+(c+d)
                formula += "("+numsTemp[0]+ operatorTemp[0]+numsTemp[1]+")"+ operatorTemp[1]
                        +"("+numsTemp[2]+operatorTemp[2]+numsTemp[3]+")";
                if(evaluateExpression(formula) == 24){
                    System.out.println(formula);
                }

                formula = "";
                // 加括号的第二种情况:  ((a+b)+c)+d,
                formula += "(("+numsTemp[0]+ operatorTemp[0]+numsTemp[1]+")"+ operatorTemp[1]+numsTemp[2]
                        +")"+operatorTemp[2]+numsTemp[3];

                if(evaluateExpression(formula) == 24){
                    System.out.println(formula);
                }

                formula = "";
                // 加括号的第三种情况: (a+(b+c))+d
                formula += "("+numsTemp[0]+operatorTemp[0]+ "(" +numsTemp[1]+operatorTemp[1]
                        +numsTemp[2]+"))"+operatorTemp[2]+numsTemp[3];

                if(evaluateExpression(formula) == 24){
                    System.out.println(formula);
                }
            }
        }
    }

    /** 计算表达式 */
    public static int evaluateExpression(String expression) {
        // 创建操作数的stack
        GenericStack<Integer> operandStack = new GenericStack<Integer>();

        // 创建操作符的stack
        GenericStack<Character> operatorStack = new GenericStack<Character>();

        // 真正的操作数和操作符
        // 去掉首尾空格
        java.util.StringTokenizer tokens = new java.util.StringTokenizer(
                expression, "()+-/*", true);

        // 步骤1:搜索token
        while (tokens.hasMoreTokens()) {
            String token = tokens.nextToken().trim(); // 压缩一个token
            if (token.length() == 0) // 为空时
                continue; // 返回到循环压缩下一个字符
            else if (token.charAt(0) == '+' || token.charAt(0) == '-') {
                // Process all +, -, *, / in the top of the operator stack
                // 把所有的 +,-,*,/ 都放在operator栈中
                while (!operatorStack.isEmpty()
                        && (operatorStack.peek() == '+' || operatorStack.peek() == '-'
                        || operatorStack.peek() == '*' || operatorStack.peek() == '/')) {
                    processAnOperator(operandStack, operatorStack);
                }

                // 把 + 或者 - 放进operator stack中
                operatorStack.push(token.charAt(0));
            } else if (token.charAt(0) == '*' || token.charAt(0) == '/') {
                while (!operatorStack.isEmpty()
                        && (operatorStack.peek() == '*' || operatorStack.peek() == '/')) {
                    processAnOperator(operandStack, operatorStack);
                }


                operatorStack.push(token.charAt(0));
            } else if (token.trim().charAt(0) == '(') {
                operatorStack.push('(');
            } else if (token.trim().charAt(0) == ')') {

                while (operatorStack.peek() != '(') {
                    processAnOperator(operandStack, operatorStack);
                }

                operatorStack.pop();
            } else {

                operandStack.push(new Integer(token));
            }
        }


        while (!operatorStack.isEmpty()) {
            processAnOperator(operandStack, operatorStack);
        }

        // 返回结果
        return operandStack.pop();
    }

    public static void processAnOperator(GenericStack<Integer> operandStack,
                                         GenericStack<Character> operatorStack) {
        char op = operatorStack.pop();
        int op1 = operandStack.pop();
        int op2 = operandStack.pop();
        if (op == '+')
            operandStack.push(op2 + op1);
        else if (op == '-')
            operandStack.push(op2 - op1);
        else if (op == '*')
            operandStack.push(op2 * op1);
        else if (op == '/'){
            operandStack.push(0);
        }
    }

    /**
     * 产生数的排列
     * @param v
     * @param left
     * @param right
     */
    public static void perm(int[] v, int left, int right) {
        if (left == right) {
            int[] temp = new int[v.length];
            for (int i = 0; i < v.length; i++) {
                temp[i] = v[i];
            }
            resultList.add(temp);
        } else {
            for (int i = left; i <= right; i++) {
                swap(v, left, i);
                perm(v, left + 1, right);
                swap(v, left, i);
            }
        }
    }

    /**
     * 产生操作符的排列
     * @param v
     * @param left
     * @param right
     */
    public static void perm(String[] v, int left, int right) {
        if (left == right) {
            String[] temp = new String[v.length];
            for (int i = 0; i < v.length; i++) {
                temp[i] = v[i];
            }
            operatorList.add(temp);
        } else {
            for (int i = left; i <= right; i++) {
                swap(v, left, i);
                perm(v, left + 1, right);
                swap(v, left, i);
            }
        }
    }

    private static void swap(int[] v, int left, int i) {
        int temp = v[left];
        v[left] = v[i];
        v[i] = temp;
    }

    private static void swap(String[] v, int left, int i) {
        String temp = v[left];
        v[left] = v[i];
        v[i] = temp;
    }

    public static void main(String[] args){
        int a = (int)(Math.random()*9+1);
        int b = (int)(Math.random()*9+1);
        int c = (int)(Math.random()*9+1);
        int d = (int)(Math.random()*9+1);


        int[] nums = {a,b,c,d};
//                int[] nums = {7,3,9,7};
//                int[] nums = {3,4,8,3};
        System.out.println("生成的四个数字为:"+a+" "+b+" "+c+" "+d);
        System.out.println("所有的表达式为:");
        findAllSolution(nums);


    }
}

测试数据如下:

采用的是随机生成的四个数字,并求出能否得到24点。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值