乐趣区

用堆栈实现表达式的计算2

public class CalculateDemo2 {
    /*
    上个题目只计算小于 10 的数字的加减乘除,本题目进行扩展,扩展到对任意正整数数字
    130+12*6-2 = 200
    步骤还是一样,只是在对数字进行入栈操作时,要多进行一下判断,把多位数字组成的字符拼接成一个数字
     */

    public double calculate(String exp) {Stack<Character> opStack = new Stack();
        Stack<Double> numStack = new Stack();
        StringBuilder num = new StringBuilder(); // 记录多个连续字符拼接成的整整数 例如 "128"
        for (int i = 0; i < exp.length(); i++) {char c = exp.charAt(i);
            if (isOp(c)) { // 操作符
                if (opStack.isEmpty()) opStack.push(c);
                else {
                    // 若当前操作符 c 优先级 <= 栈顶操作符
                    if (priority(c) <= priority(opStack.peek())) {double n1 = numStack.pop();
                        double n2 = numStack.pop();
                        char op = opStack.pop();
                        double res = calculate(n2, n1, op);
                        // pop 两个数字和一个操作符(注意顺序)计算结果入栈 并把当前操作符入栈
                        numStack.push(res);
                        opStack.push(c);
                    } else {
                        // 否则直接把当前操作符入栈
                        opStack.push(c);
                    }
                }
            } else { // 是数字,在这里对多位字符表示的数字进行扩展!!!num.append(c);
                if (i == exp.length() - 1) { // 如果当前字符已经达到表达式最后,则直接把 num 转换成数字,入栈
                    numStack.push(Double.parseDouble(num.toString()));
                    num.delete(0, num.length());
                } else {
                    // 判断下一个字符是不是数字,如果是数字就继续扫描,如果是运算符,则把 num 转成数字,入栈
                    if (isOp(exp.charAt(i + 1))) { // 下一位是运算符
                        numStack.push(Double.parseDouble(num.toString()));
                        // 这里要把 num 清空
                        num.delete(0, num.length());
                    }
                }
            }
        }
        // 现在栈中存放的都是优先级一样的操作符,按 pop 顺序进行计算,结果入栈
        while (!opStack.isEmpty()) {char op = opStack.pop();
            double n1 = numStack.pop();
            double n2 = numStack.pop();
            double res = calculate(n2, n1, op);
            numStack.push(res);
        }
        // 最终数字栈剩余一个数字,就是表达式的最终结果
        return numStack.pop();}

    public double calculate(double a, double b, char c) {if (c == '+') return a + b;
        if (c == '-') return a - b;
        if (c == '*') return a * b;
        if (c == '/') return a / b;
        throw  new RuntimeException("invalid input");
    }
    public boolean isOp(char c) {return c == '+' || c == '-' || c == '*' || c == '/';}
    public int priority(char c) {if (c == '+' || c == '-') return 1;
        if (c == '*' || c == '/') return 2;
        return -1;
    }
    public static void main(String[] args) {
        String exp = "130+12*6-2";
        String exp1 = "7*2*2-5+1-5+3-4";
        CalculateDemo2 app = new CalculateDemo2();
        System.out.println(app.calculate(exp));
        System.out.println(app.calculate(exp1));
    }
}
退出移动版