核心陷阱是弹栈顺序错误(右操作数必须先弹)和除零未检查;逐字符解析会错误拆分负数与多位数,应先分词再判断类型,stoi可安全处理“-5”等格式。

直接用 std::stack 就行,别自己写栈;核心陷阱只有两个:弹栈顺序搞反、除零没检查。
为什么不能逐字符解析 tokens?
因为 "-123" 是一个 token,不是 "-" 和 "123" 两个;"100" 是一个整数,不是三个字符。逐字符扫会把负数拆成运算符加数字,导致栈错乱。
- 正确做法是先按空格切分(用
std::istringstream或手动遍历空格),得到字符串 vector,每个元素是一个完整 token - 对每个 token 判断:
token == "+" || token == "-" || token == "*" || token == "/"—— 只有不匹配才走stoi(token) -
stoi能正确处理"-5"、"+42"、"0",无需额外逻辑
std::stack 弹栈时谁是左操作数、谁是右操作数?
顺序绝对不能错:先 pop() 出来的是右操作数,后 pop() 出来的是左操作数。比如表达式 ["5","2","-"],栈状态是 [5,2],遇到 "-" 时必须先取 2(右),再取 5(左),算 5 - 2。
- 错误写法:
int a = st.top(); st.pop(); int b = st.top(); st.pop(); st.push(a - b);→ 算的是2 - 5 - 正确写法:
int b = st.top(); st.pop(); int a = st.top(); st.pop(); st.push(a - b); - 减法和除法对顺序敏感;加法乘法虽交换律成立,但统一逻辑更安全
除零和栈空怎么检查才不崩溃?
真实输入不可信,"/" 前必须确保栈里至少有两个数,且右操作数(第二个弹出的)不能为 0。不检查就调 st.top() 或执行除法,会触发 std::out_of_range 或 SIGFPE。
- 每次遇到运算符前,先写
if (st.size() - 遇到
"/"时,拿到右操作数后立刻判断:if (b == 0) throw std::runtime_error("division by zero"); - 别依赖
try-catch stoi来兜底非法 token——提前过滤或定义明确错误码更可控
最易被忽略的是:逆波兰求值本身完全不需要运算符优先级逻辑。如果你在 evalRPN 函数里还写了优先级表或条件分支去“决定要不要算”,说明你混淆了中缀转后缀和后缀求值两个阶段——后者只管按 token 顺序立即执行。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











