Implement a basic calculator to evaluate a simple expression string.
The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces ``.
Example 1:
Input: "1 + 1"Output: 2
Example 2:
Input: " 2-1 + 2 "Output: 3
Example 3:
Input: "(1+(4+5+2)-3)+(6+8)"Output: 23
Note:
- You may assume that the given expression is always valid.
- Do not use the
evalbuilt-in library function.
题意
计算只包含”+”、”-“、”(“、”)”和非负整数的字符串的值。
思路
正向遍历:从前向后遍历字符串,如果是数字则将其加入到结果res中;如果是操作符则对应变更sign的值;如果是’(‘则将当且结果res和sign依次压入栈中,重置res为0、sign为1;如果是’)’,说明当前括号中所有值已经计算完毕,将其与栈中元素相加(减)。
反向遍历:从后向前遍历字符串,如果是数字则压入操作数栈;如果是’)’、’+’、’-‘则压入操作符栈;如果是’(‘则从操作数栈(注意前后顺序,先出栈的就是在前面的操作数)和操作符栈出栈,计算结果后重新压入操作数栈,直到将对应的’)’出栈。
代码实现 - 正向遍历
class Solution {public int calculate(String s) {int res = 0, sign = 1;Deque<Integer> stack = new ArrayDeque<>();for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);if (c == ' ') {continue;} else if (c == '+' || c == '-') {sign = c == '+' ? 1 : -1;} else if (c == '(') {stack.push(res);stack.push(sign);res = 0;sign = 1;} else if (c == ')') {res *= stack.pop();res += stack.pop();} else {int num = c - '0';// 计算出完整的数字while (i + 1 < s.length() && s.charAt(i + 1) >= '0' && s.charAt(i + 1) <= '9') {num = num * 10 + s.charAt(i + 1) - '0';i++;}res += sign * num;}}return res;}}
代码实现 - 反向遍历
class Solution {public int calculate(String s) {Deque<Character> ops = new ArrayDeque<>(); // 操作符栈Deque<Integer> nums = new ArrayDeque<>(); // 操作数栈for (int i = s.length() - 1; i >= 0; i--) {char c = s.charAt(i);if (c == ' ') {continue;} else if (c == ')') {ops.push(c);} else if (c == '(') {char op = ops.pop();while (op != ')') {int a = nums.pop(), b = nums.pop();nums.push(a + (op == '+' ? b : -b));op = ops.pop();}} else if (c == '+' || c == '-') {ops.push(c);} else {// 需要先将连带的数字全部找出,组合成对应的整数int num = c - '0';int tens = 10;while (i - 1 >= 0 && s.charAt(i - 1) >= '0' && s.charAt(i - 1) <= '9') {num = (s.charAt(i - 1) - '0') * tens + num;i--;tens *= 10;}nums.push(num);}}while (nums.size() != 1) {int a = nums.pop(), b = nums.pop();char op = ops.pop();nums.push(a + (op == '+' ? b : -b));}return nums.pop();}}
