题解 | #四则运算#
四则运算
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()); } }