
中缀转后缀时,运算符优先级怎么比较才不出错
直接用 std::map 存 char 到优先级的映射容易翻车——比如 '+' 和 '-' 优先级相同但必须左结合,而 '^'(若支持)通常右结合。更稳妥的是写个内联函数,把结合性也纳入判断逻辑。
常见错误现象:2 + 3 * 4 转成 2 3 + 4 *(错),本质是没在栈顶运算符 ≥ 当前运算符时弹出栈顶。
- 左结合运算符(
+,-,*,/):当栈顶优先级 ≥ 当前,就弹出 - 右结合(如
^):只在栈顶优先级 > 当前才弹出 - 遇到
'('直接入栈;遇到')'就一直弹出直到'('(不保留括号)
数字和多位数怎么正确切分
别用单字符遍历然后挨个拼字符串——遇到负数 -5 或浮点数 3.14 就崩。真实场景里,输入往往是 std::string,得边扫边识别 token。
使用场景:表达式含空格("12 + -3.5")、负号开头、科学计数法(虽少见但要防)。
立即学习“C++免费学习笔记(深入)”;
- 跳过空格后,先看是否为
'-'或'+',再判断后面是不是数字或小数点 - 用
std::stod或std::stoi解析数字时,传入size_t*获取实际解析长度,避免截断 - 遇到非数字、非小数点、非符号的字符,立刻停——那是运算符或括号
用 std::stack<char> 存运算符够不够
够,但仅限纯运算符+括号。如果后续要扩展函数调用(如 sin(3.14)),栈里就得存 std::string 或自定义类型。现在先别搞复杂,char 省事且快。
性能影响:用 std::stack 比手写数组栈稍慢一点,但对一般表达式(百字符内)可忽略;兼容性上,所有标准库都支持。
- 别用
std::stack::top()前不检查empty()——触发未定义行为 - 弹出
'('后记得丢弃,别塞进输出队列 - 扫描完后,把栈里剩余运算符全弹出——漏这步会导致
1+2+3变成1 2 +(缺最后一个+)
为什么输出要用 std::queue<std::string> 而不是 vector
因为后缀表达式要求严格顺序输出:操作数先来,运算符后到,且每个元素独立。用 std::queue 语义清晰,push() / front() / pop() 天然匹配“先进先出”需求;用 vector 虽然也能做,但容易误用 push_back() 后又按索引乱访问。
容易踩的坑:把操作数(如 "123")和运算符(如 "+")统一存成 std::string,别混用 char 和 std::string——否则输出时类型不一致,operator<< 可能静默截断。
- 数字 token 直接
queue.push(token_str) - 运算符也转成
std::string(1, op)再入队,保持类型一致 - 最终遍历 queue 时,用
while (!q.empty()) { std::cout << q.front() << " "; q.pop(); }
最易被忽略的是负号和减号的二义性——同一个 '-' 字符,可能是运算符,也可能是数字的一部分。不提前区分,后面解析阶段根本没法还原原意。这一步卡住,整个转换就从语义上错了。










