1. 题目
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/cc87ecdab679bdb67e34b1ea1aa643ec.png#pic_center)
2. 思路
(1) 栈
- 利用一个栈存放操作数,另一个栈存放操作符。
- 若遇到左括号,则直接压入操作符栈中;若遇到右括号,则弹出操作符栈的栈顶元素,以及两个操作数栈的栈顶元素进行计算,结果压入操作数栈中,如此循环,直到操作符栈的栈顶元素是左括号,则直接弹出即可。
- 若遇到数字,则直接压入操作数栈中。
- 若遇到操作符,可以先判断操作符栈的栈顶元素的优先级是否大于或等于当前操作符,若大于或等于,则可以先将之前的操作计算出来,然后再将操作符压入操作符栈中。
3. 代码
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
public class Test {
public static void main(String[] args) {
}
}
class Solution {
public Map<Character, Integer> map = new HashMap<Character, Integer>() {{
put('-', 1);
put('+', 1);
put('*', 2);
}};
public int solve(String s) {
char[] cs = s.toCharArray();
int n = s.length();
Deque<Integer> nums = new LinkedList<>();
nums.addLast(0);
Deque<Character> ops = new LinkedList<>();
for (int i = 0; i < n; i++) {
char c = cs[i];
if (c == '(') {
ops.addLast(c);
} else if (c == ')') {
while (!ops.isEmpty()) {
if (ops.peekLast() != '(') {
calc(nums, ops);
} else {
ops.pollLast();
break;
}
}
} else {
if (Character.isDigit(c)) {
int num = 0;
int j = i;
while (j < n && Character.isDigit(cs[j])) {
num = num * 10 + (cs[j++] - '0');
}
nums.addLast(num);
i = j - 1;
} else {
if (i > 0 && (cs[i - 1] == '(' || cs[i - 1] == '+' || cs[i - 1] == '-')) {
nums.addLast(0);
}
while (!ops.isEmpty() && ops.peekLast() != '(') {
char prev = ops.peekLast();
if (map.get(prev) >= map.get(c)) {
calc(nums, ops);
} else {
break;
}
}
ops.addLast(c);
}
}
}
while (!ops.isEmpty() && ops.peekLast() != '(') {
calc(nums, ops);
}
return nums.peekLast();
}
public void calc(Deque<Integer> nums, Deque<Character> ops) {
if (nums.isEmpty() || nums.size() < 2 || ops.isEmpty()) {
return;
}
int b = nums.pollLast();
int a = nums.pollLast();
char op = ops.pollLast();
int res = 0;
if (op == '+') {
res = a + b;
} else if (op == '-') {
res = a - b;
} else if (op == '*') {
res = a * b;
}
nums.addLast(res);
}
}