应使用std::stack,按空格切分token后逐个匹配运算符,非运算符再stoi;减法除法需先弹右操作数再弹左操作数;每次pop前必须检查栈大小以防未定义行为。

直接用 std::stack<int></int> 就行,别自己手写栈、别提前 reserve、别在运算符判断里搞优先级逻辑——那些都是典型误入歧途。
token 切分与类型识别必须按空格分割后逐个比对运算符
不能对字符串逐字符扫描,否则 "-123" 会被拆成 "-" 和 "123",导致错误地当作减法操作;也不能无条件调 stoi(),因为 "+" 或 "-" 单独出现时不是数字。
- 用
std::istringstream或循环遍历tokensvector(题目通常已切好) - 对每个
token先检查是否等于"+"、"-"、"*"、"/" - 只有不匹配时才走
stoi(token)——它天然支持负数和多位数 - 别写
isNumber()函数去遍历字符判断正负号,纯属重复造轮子且易漏边界
弹栈顺序错一丁点,减法除法全崩
栈是后进先出,所以对表达式 ["5","2","-"],压栈顺序是 5 → 2,遇到 "-" 时:先 st.top() 拿到 2(右操作数),st.pop() 后再 st.top() 拿到 5(左操作数),算的是 5 - 2。顺序反了就是 2 - 5,结果差两倍。
- 必须严格:先弹
right = st.top(); st.pop();,再弹left = st.top(); st.pop(); -
switch (s[0])可以,但别用s.c_str()配atoi——stoi更安全,抛异常可捕获 - 除法不用额外截断:C++ 整数除法本就是向零取整,
-5 / 2 == -2,符合题设要求
边界检查不是“以防万一”,而是必做动作
合法输入只是 OJ 的简化假设。真实场景下,tokens = ["+"] 或 ["1", "/"] 会直接让 st.top() 访问空栈,触发未定义行为甚至段错误。
立即学习“C++免费学习笔记(深入)”;
- 每次弹栈前检查
st.size() ,立即 <code>throw std::runtime_error("not enough operands") - 遇到
"/"时,拿到right后立刻判断是否为 0,是则报错——别等left / right执行完才发现 - 对非法 token(如
"abc")套try { stoi(s) } catch (const std::invalid_argument&),避免程序终止 - 用
long long临时存中间结果?没必要。题设明确“答案可用 32 位整数表示”,int足够,且std::stack<int></int>内存更紧凑
最常被跳过的其实是弹栈前的栈大小检查——很多人只在最后 return st.top() 前判一次,但中间每步运算都可能因输入残缺而崩溃。这不是健壮性加分项,是运行正确的底线。


















