题解 | #四则运算#

四则运算

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());
    }

}
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务