题解 | #四则运算#
四则运算
http://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e
双栈操作,碰到这种的,不知道怎么弄,要快速去学习前辈的知识,而不是自己在哪里瞎搞。
import java.util.*;
/**
* @author zfc
* @date 2021/9/8 16:11
*/
public class Calculator {
private static boolean isNumber(char c) {
return Character.isDigit(c);
}
private static char opposite(char c) {
if (c == ')') {
return '(';
} else if (c == ']') {
return '[';
} else if (c == '}') {
return '{';
} else {
return '\0';
}
}
private static void calc(Deque<Integer> nums, Deque<Character> ops) {
if (ops.isEmpty() || nums.size() < 2) return;
char c = ops.pollLast();
int ans = 0;
int x = nums.pollLast();
int y = nums.pollLast();
if (c == '+') ans = x + y;
else if (c == '-') ans = y - x;
else if (c == '*') ans = x * y;
else if (c == '/') ans = y / x;
else throw new IllegalArgumentException();
nums.add(ans);
}
public static void main(String[] args) {
Map<Character, Integer> map = new HashMap<Character, Integer>() {{
put('+', 1);
put('-', 1);
put('*', 2);
put('/', 2);
}};
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
sc.close();
s = s.replaceAll(" ", "");
System.out.println(s);
char[] crs = s.toCharArray();
int n = crs.length;
//替换掉所有的空格
Deque<Integer> nums = new ArrayDeque<Integer>();
// 防止首字母为 - 号或者 +号
nums.add(0);
Deque<Character> ops = new ArrayDeque<Character>();
for (int i = 0; i < n; i++) {
char c = crs[i];
if (c == '(' || c == '[' || c == '{') {
ops.addLast(c);
} else if (c == ')' || c == ']' || c == '}') { // 开始计算
char left = opposite(c);
while (!ops.isEmpty()) {
if (ops.peekLast() != left) {
calc(nums, ops);
} else {
// 删除左边的括号元素
ops.pollLast(); //结束计算 将操操作符移除栈
break;
}
}
} else {
if (isNumber(c)) {
int u = 0;
int j = i;
while (j < n && isNumber(crs[j])) u = u * 10 + crs[j++] - '0';
// 多加了1次.
nums.addLast(u);
i = j-1;
} else { // 碰到操作符然后判断是否都对栈内已经有的元素进行计算.
if (i > 0 && (crs[i-1] == '(' || crs[i-1] == '[') || crs[i-1] == '{') nums.add(0);
// 有一个新操作要入栈时,先把栈内可以算的都算了
while (!ops.isEmpty() && ops.peekLast() != '(' && ops.peekLast() != '[' && ops.peekLast() != '{') {
char prev = ops.peekLast();
// 前一个操作符和当前操作符的优先级在同一个级别上的时候,或者大于当前优先级,才开始计算.
if (map.get(prev) >= map.get(c)) {
calc(nums, ops);
} else {
break;
}
}
ops.addLast(c);
}
}
}
// 计算完栈内的剩余操作.
while (!ops.isEmpty()) calc(nums, ops);
System.out.println(nums.peekLast());
}
} 
查看20道真题和解析