AcWing 3302. Java-表达式求值
原题链接
简单
作者:
zlnnjit
,
2021-03-20 01:00:15
,
所有人可见
,
阅读 523
使用「双栈」解决「究极表达式计算」问题
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println(calculate(sc.nextLine()));
}
private static Map<Character, Integer> map = new HashMap() {{
put('+', 1);
put('-', 1);
put('*', 2);
put('/', 2);
put('%', 2);
put('^', 3);
}};
public static int calculate(String s) {
//s预处理
s = s.replaceAll(" ", "");
s = s.replaceAll("\\(-", "(0-");
char[] chs = s.toCharArray();
//定义双栈
Deque<Integer> nums = new ArrayDeque<>();
nums.addLast(0);
Deque<Character> opts = new ArrayDeque<>();
//开始模拟计算
for (int i = 0; i < chs.length; i++) {
char ch = chs[i];
if (ch == '(') {
//左括号处理:直接放入opts栈中
opts.addLast(ch);
} else if (ch == ')') {
//右括号处理:计算到最近的左括号
while (!opts.isEmpty()) {
if (opts.peekLast() != '(') {
calculate(nums, opts);
} else {
opts.pollLast();
break;
}
}
} else if (Character.isDigit(ch)) {
//数字处理:取出[完整]数字放入nums栈中
int num = 0;
while (i < chs.length && Character.isDigit(chs[i])) num = num * 10 + (chs[i++] - '0');
i--;
nums.addLast(num);
} else {
//运算符号处理:处理opts栈顶元素比当前字符优先级高的元素
while (!opts.isEmpty() && opts.peekLast() != '(' && map.get(opts.peekLast()) >= map.get(ch)) {
calculate(nums, opts);
}
opts.addLast(ch);
}
}
//处理剩余计算
while (!opts.isEmpty()) calculate(nums, opts);
//返回计算结果
return nums.pollLast();
}
private static void calculate(Deque<Integer> nums, Deque<Character> opts) {
int a = nums.pollLast(), b = nums.pollLast(), ans = 0;
char opt = opts.pollLast();
switch (opt) {
case '+':
ans = b + a;
break;
case '-':
ans = b - a;
break;
case '*':
ans = b * a;
break;
case '/':
ans = b / a;
break;
case '%':
ans = b % a;
break;
case '^':
ans = (int) Math.pow(b, a);
}
nums.addLast(ans);
}
}