【双栈】定义两个栈nums和ops分别存数字和操作符,定义一个计算函数,传入当前的操作符,计算所有优先级>=该操作符的表达式。
1.预处理:replace掉所有的空格,在字符串前加个0,防止不讲武德上来就给个负数。
2.如果遇到数字,通过t*10+c-‘0’计算值
3.如果遇到'('直接插入ops
4.如果遇到')'则计算到前面出现'('
5.其他操作符,计算前面优先级比他高或者和他相同的
class Solution {
// 双栈 3:04 35
Deque<Integer> nums = new LinkedList();
Deque<Character> ops = new LinkedList();
Map<Character, Integer> map = new HashMap(){{
put('*', 2);
put('/', 2);
put('+', 1);
put('-', 1);
put('#', 0);
}};
void show() {
for (var x: nums) {
System.out.print(x + ",");
}
System.out.println();
for (var x: ops) {
System.out.print(x + ",");
}
System.out.println();
}
void calculate(char next) {
// show();
while (!ops.isEmpty()) {
char op = ops.poll();
if (op == '(') {
if (op == ')') ops.push(op);
break;
}
if (map.get(op) >= map.get(next)) {
if (op == '-') {
int top = nums.pop();
nums.push(nums.pop() - top);
} else if (op == '+') {
nums.push(nums.pop() + nums.pop());
} else if (op == '*') {
nums.push(nums.pop() * nums.pop());
} else {
int top = nums.pop();
nums.push(nums.pop() / top);
}
} else {
ops.push(op);
break;
}
}
}
public int calculate(String s) {
s = s.replace(" ", "");
s = "0" + s;
int n = s.length(), t = 0, flag = 0;
for (var i = 0; i < n; i++) {
char c = s.charAt(i);
if (c == '(') {
ops.push(c);
} else if (c == ')') {
if (flag == 1) {
nums.push(t); flag = 0; t = 0;
}
calculate(c);
} else if (c == '+' || c == '-' || c == '*' || c == '/') {
if (c == '-') {
if (s.charAt(i - 1) == '(') {
nums.push(0); continue;
}
}
if (flag == 1) {
nums.push(t); flag = 0; t = 0;
}
calculate(c);
ops.push(c);
} else {
t = t * 10 + c - '0';
flag = 1;
if (i == n - 1) nums.push(t);
}
}
// for (var x: nums) {
// System.out.print(x + " ");
// }
calculate('#');
// show();
return nums.pop();
}
}