小学生都能看懂的题解 | #表达式求值#

表达式求值

https://www.nowcoder.com/practice/c215ba61c8b1443b996351df929dc4d4

目标

我们要做一个计算器,它可以做加法、减法和乘法,并且还能理解括号,这意味着先做括号里面的计算。

工具

我们会用到两个堆叠的东西(就像叠罗汉一样),一个用来放数字,另一个用来放符号。

数字堆叠(Numbers Stack)

这个堆叠是用来存数字的,当我们计算完一部分的时候,就把答案放在这里。

符号堆叠(Operators Stack)

这个堆叠是用来存加号、减号和乘号这些符号的,还有括号也会放在这里。

步骤

  1. 读取每一个字符:我们像读书一样,从左到右一个一个字符来看。
  2. 如果是数字:我们就把这个数字保存起来,然后放到数字堆叠里。
  3. 如果是加号或减号:我们需要看看符号堆叠里面有没有东西,如果有比它优先级高的符号(比如说已经有的乘号),就需要先做计算,然后把结果放回数字堆叠里,再把新的符号放进去。
  4. 如果是乘号:因为乘法要先做,所以我们需要看看符号堆叠里面有没有乘号,如果有就先做乘法,然后再把新的乘号放进去。
  5. 如果是左括号(((:直接放进符号堆叠。
  6. 如果是右括号()):我们需要一直做里面的计算,直到找到匹配的左括号。
  7. 如果是空格:就跳过它。
  8. 如果是其他字符:我们不认得它,所以报错。

最后

当所有的字符都读完了,我们再把符号堆叠里的东西全做完,最后留在数字堆叠里的就是答案。

下面是具体代码实现:

import java.util.Stack;

public class SimpleCalculator {

    public static int solve(String expression) {
        Stack<Integer> numbersStack = new Stack<>(); // 存放数字
        Stack<Character> operatorsStack = new Stack<>(); // 存放操作符
        
        int index = 0;
        while (index < expression.length()) {
            char currentChar = expression.charAt(index);
            
            if (Character.isDigit(currentChar)) { // 如果是数字
                int number = 0;
                while (index < expression.length() && Character.isDigit(expression.charAt(index))) {
                    number = number * 10 + (expression.charAt(index++) - '0');
                }
                numbersStack.push(number); // 把数字存入数字栈
            } else if (currentChar == '+' || currentChar == '-' || currentChar == '*') { // 如果是操作符
                // 根据需要调整操作符栈
                while (!operatorsStack.isEmpty() && precedence(operatorsStack.peek()) >= precedence(currentChar)) {
                    numbersStack.push(applyOperation(operatorsStack.pop(), numbersStack.pop(), numbersStack.pop()));
                }
                operatorsStack.push(currentChar); // 把操作符存入操作符栈
                index++;
            } else if (currentChar == '(') { // 如果是左括号
                operatorsStack.push(currentChar);
                index++;
            } else if (currentChar == ')') { // 如果是右括号
                while (operatorsStack.peek() != '(') {
                    numbersStack.push(applyOperation(operatorsStack.pop(), numbersStack.pop(), numbersStack.pop()));
                }
                operatorsStack.pop(); // 移除左括号
                index++;
            } else if (currentChar == ' ') { // 如果是空格
                index++;
            } else {
                System.out.println("不支持的操作符:" + currentChar);
                index++;
            }
        }

        // 计算剩余的操作符
        while (!operatorsStack.isEmpty()) {
            numbersStack.push(applyOperation(operatorsStack.pop(), numbersStack.pop(), numbersStack.pop()));
        }

        return numbersStack.pop(); // 返回最终的答案
    }

    private static int applyOperation(char operation, int b, int a) {
        switch (operation) {
            case '+':
                return a + b;
            case '-':
                return a - b;
            case '*':
                return a * b;
            default:
                return 0;
        }
    }

    private static int precedence(char op) {
        switch (op) {
            case '+':
            case '-':
                return 1;
            case '*':
                return 2;
            case '(':
                return 0;
            default:
                return -1;
        }
    }
}

如果这篇文章对你有帮助,请点个免费的赞👍,让它帮助更多的人。

#牛客创作赏金赛#
小学生都能看懂的算法 文章被收录于专栏

主要面向小白的算法文章。以小学生都能看懂为目标而编写,顺便巩固下自己。

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务