小学生都能看懂的题解 | #表达式求值#
表达式求值
https://www.nowcoder.com/practice/c215ba61c8b1443b996351df929dc4d4
目标
我们要做一个计算器,它可以做加法、减法和乘法,并且还能理解括号,这意味着先做括号里面的计算。
工具
我们会用到两个堆叠的东西(就像叠罗汉一样),一个用来放数字,另一个用来放符号。
数字堆叠(Numbers Stack)
这个堆叠是用来存数字的,当我们计算完一部分的时候,就把答案放在这里。
符号堆叠(Operators Stack)
这个堆叠是用来存加号、减号和乘号这些符号的,还有括号也会放在这里。
步骤
- 读取每一个字符:我们像读书一样,从左到右一个一个字符来看。
- 如果是数字:我们就把这个数字保存起来,然后放到数字堆叠里。
- 如果是加号或减号:我们需要看看符号堆叠里面有没有东西,如果有比它优先级高的符号(比如说已经有的乘号),就需要先做计算,然后把结果放回数字堆叠里,再把新的符号放进去。
- 如果是乘号:因为乘法要先做,所以我们需要看看符号堆叠里面有没有乘号,如果有就先做乘法,然后再把新的乘号放进去。
- 如果是左括号(((:直接放进符号堆叠。
- 如果是右括号()):我们需要一直做里面的计算,直到找到匹配的左括号。
- 如果是空格:就跳过它。
- 如果是其他字符:我们不认得它,所以报错。
最后
当所有的字符都读完了,我们再把符号堆叠里的东西全做完,最后留在数字堆叠里的就是答案。
下面是具体代码实现:
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; } } }
如果这篇文章对你有帮助,请点个免费的赞👍,让它帮助更多的人。
#牛客创作赏金赛#小学生都能看懂的算法 文章被收录于专栏
主要面向小白的算法文章。以小学生都能看懂为目标而编写,顺便巩固下自己。