HJ50 四则运算

题目:

HJ50 四则运算

题解一:

难点:

  1. 括号优先计算
  2. 正负号和运算符加减号区分
  3. 运算符优先级

解决方案:

  1. 运算符栈存放运算符
  2. 数字栈存放数字
  3. 每次计算从数字栈弹出两个数字,运算符栈弹出一个运算符
  4. 数字前面的+,-为正负号,数字后面的+,-为运算符号,设置一个标记用以区分
  5. 遇到括号优先计算


    public int expressCalculate(String s) {
        if (s == null || s.length() == 0) {
            return 0;
        }

        // 替换括号
        s = s.replaceAll("\\[", "(");
        s = s.replaceAll("\\{", "(");
        s = s.replaceAll("\\]", ")");
        s = s.replaceAll("\\}", ")");

        // 加一个小括号在最外层
        if (s.charAt(0) != '(') {
            s = "(" + s + ")";
        }

        Stack<Character> operatorStack = new Stack<>();
        Stack<Integer> numberStack = new Stack<>();
        boolean flag = false;
        for (int i = 0; i < s.toCharArray().length; i++) {
            char c = s.charAt(i);
            if (c == '(') {
                operatorStack.push(c);
            } else if (c == ')') {
                // 遇到右括号就计算
                while (operatorStack.peek() != '(') {
                    calculateAndPush(numberStack, operatorStack);
                }
                operatorStack.pop();
            } else if (flag) {
                // 运算符,如果栈顶的运算符优先级高就需要先计算
                while (priority(operatorStack.peek(), c)) {
                    calculateAndPush(numberStack, operatorStack);
                }
                operatorStack.push(c);
                // 运算符结束,后面的+,-就是正负号
                flag = false;
            } else {
                // 数字
                int j = i;
                // 正负号
                if (c == '-' || c == '+') {
                    i++;
                }

                while (Character.isDigit(s.charAt(i))) {
                    i++;
                }

                // 转换数字
                int number = Integer.valueOf(s.substring(j, i));
                numberStack.push(number);
                // 数字结束,后面+,-就是运算符
                flag = true;
                // for 循环后面i++,所以这里需要先减一
                i--;
            }
        }

        return numberStack.pop();
    }

    private boolean priority(char stackOperator, char currentOperator) {
        if (stackOperator == '(') {
            return false;
        }

        if ((stackOperator == '+' || stackOperator == '-') && (currentOperator == '*' || currentOperator == '/')) {
            return false;
        }

        return true;
    }

    private void calculateAndPush(Stack<Integer> numberStack, Stack<Character> operatorStack) {
        // 注意:栈的顺序是反的,这里先出栈的是参数二
        int value2 = numberStack.pop();
        int value1 = numberStack.pop();
        char operator = operatorStack.pop();

        int result = 0;
        switch (operator) {
            case '+' : result = value1 + value2; break;
            case '-' : result = value1 - value2; break;
            case '*' : result = value1 * value2; break;
            case '/' : result = value1 / value2; break;
        }

        numberStack.push(result);
    }

时间复杂度:O(N)

题解二:脚本执行

把表达式作为脚本执行,使用JavaScript脚本直接计算结果。

    public int expressCalculate(String s) throws Exception {
        if (s == null || s.length() == 0) {
            return 0;
        }

        // 替换括号
        s = s.replaceAll("\\[", "(");
        s = s.replaceAll("\\{", "(");
        s = s.replaceAll("\\]", ")");
        s = s.replaceAll("\\}", ")");

        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
        ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("Nashorn");
        return (int) scriptEngine.eval(s);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值