计算器正确处理多层嵌套运算的关键是用双栈(操作数栈和运算符栈)按优先级动态执行:括号触发内部计算,运算符优先级决定立即运算或入栈,多位数和负号需状态识别,最后清空运算符栈得结果。

计算器要正确处理多层嵌套运算(比如 3 + (5 * (2 - 1)) - 4),关键不在“多层”,而在于**如何用栈把优先级决策变成可执行的动作**。括号和乘除加减不是并列规则,而是统一服从一个逻辑:高优先级运算必须先算,低优先级的得等——栈天然适合暂存“待定项”,直到条件满足再出手。
操作数栈 + 运算符栈:两个容器各司其职
只用一个栈容易混淆数据和指令。标准做法是分设:
- 操作数栈:只存数字(包括负数、多位数解析后的整数值)
-
运算符栈:只存
+、-、*、/和(
右括号 ) 不入栈,它是个“触发信号”:一出现,就持续弹出运算符栈顶并计算,直到遇到 (——这个过程自动保证了括号内表达式被完整、优先求值。
优先级比较决定“现在算还是等等”
每读到一个运算符,不急着压栈,先看它和运算符栈顶的“脾气”是否相投:
- 若当前运算符优先级 ≤ 栈顶(如
+遇到*,或-遇到+),说明栈顶那个该先算:立刻从操作数栈弹两个数、从运算符栈弹一个符,执行运算,结果压回操作数栈 - 若当前优先级更高(如
*遇到+),说明它更“着急”,直接入栈,让后面的数先攒着 -
(优先级设为最低(比如 0),确保任何运算符都能压在它上面;)则强制清空到左括号
常见优先级设定:+/- 为 1,*// 为 2,( 为 0。
多位数和负号需要额外状态管理
字符串里连续的 '1''2''3' 是一个数 123,不是三个单数字。需用临时字符串(如 keepNum)拼接,直到遇到非数字字符才转成整数入栈。
负号处理分两种:
- 二元减号(如
5-3):当作运算符,走优先级流程 - 一元负号(如
-5或(-3+2)):在扫描时识别为“符号开头”,直接生成负数压入操作数栈,不进运算符栈
收尾阶段不能漏:清空运算符栈
表达式扫完,运算符栈里可能还剩几个没处理的符号(比如 1+2+3 最后剩下两个 +)。此时要持续弹出运算符,并从操作数栈取两个数运算,直到运算符栈为空。最终操作数栈只剩一个值——就是答案。











