227. Basic Calculator II 发表于 2022-09-02 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768class Solution { private static final Map<Character, Integer> OPERATOR_TO_PRECEDENCE_MAP = new HashMap<>(); static { OPERATOR_TO_PRECEDENCE_MAP.put('+', 0); OPERATOR_TO_PRECEDENCE_MAP.put('-', 0); OPERATOR_TO_PRECEDENCE_MAP.put('*', 1); OPERATOR_TO_PRECEDENCE_MAP.put('/', 1); } public int calculate(String s) { s = s.replaceAll(" ", ""); // 思路:将所有的操作符按照二元操作符处理 Stack<Character> operatorStack = new Stack<>(); Stack<Integer> numStack = new Stack<>(); numStack.push(0); // 放入 0 是为了处理纯负数的情况,如表达式 '-5', 此时等同于表达式 '0-5' for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (Character.isDigit(c)) { // 将后续的数字收集并统一转换为整数 int num = 0; while (i < s.length() && Character.isDigit(s.charAt(i))) { num = num * 10 + (s.charAt(i) - '0'); i++; } // i == s.length() or s.charAt(i) is not digit i--; numStack.push(num); } else { // 注意此处是 while 而不是 if, 可以用 "1*2-3/4+5*6-7*8+9/10" 进行验证,即保证从左到右计算,若使用 if 会导致乘除法计算的结果全部位于栈中,最后 "2-0+30-56+0" 从右到左计算而得到错误结果。while 的另一层含义为使操作符栈中的操作符优先级递增,以保证最后 while 计算结果正确 while (!operatorStack.isEmpty() && OPERATOR_TO_PRECEDENCE_MAP.get(operatorStack.peek()) >= OPERATOR_TO_PRECEDENCE_MAP.get(c)) { calc(operatorStack, numStack); } operatorStack.push(c); // 不要忘记将操作符入栈 } } // 注意此处是 while, 如表达式 '3+2*2', 最后操作符栈中有两个操作符,操作数栈中有三个操作数 while (!operatorStack.isEmpty()) { calc(operatorStack, numStack); } return numStack.pop(); } private void calc(Stack<Character> operatorStack, Stack<Integer> numStack) { char operator = operatorStack.pop(); int b = numStack.pop(), a = numStack.pop(); switch (operator) { case '+': numStack.push(a + b); break; case '-': numStack.push(a - b); break; case '*': numStack.push(a * b); break; case '/': numStack.push(a / b); break; default: throw new IllegalArgumentException("Unsupported operator: " + operator); } }} Reference227. Basic Calculator II面试题 16.26. 计算器