大二CS学生求助:C++栈实现中缀转后缀的字符循环扫描问题
中缀表达式转后缀表达式的循环扫描实现与代码修正
核心问题解决:循环扫描所有字符
你的代码中用char expr只能存储单个字符,这是无法处理完整表达式的根源。正确的做法是用std::string存储整个输入表达式,然后通过循环遍历字符串的每个字符来逐个处理,比如使用C++11及以上支持的范围for循环,或者传统的下标循环。
现有代码的其他致命问题
除了扫描逻辑,你的代码还有几个关键错误必须修正:
- 运算符栈
stack1是st函数的局部变量,每次调用都会重新创建,完全无法保存之前的运算符状态,必须改为全局变量或通过参数传递。 - 优先级函数的逻辑颠倒:乘除(*、/、%)优先级应高于加减(+、-),你当前的返回值设置反了,会导致运算符弹出逻辑错误。
- 右括号处理时没有弹出栈中的左括号,会导致栈残留无效字符。
- 处理运算符时仅判断一次栈顶元素,正确逻辑应该是循环弹出所有优先级大于等于当前运算符的栈顶元素。
move函数的手动读取字符逻辑完全多余,直接遍历字符串即可。
修正后的完整代码
#include <iostream> #include <stack> #include <string> #include <cctype> using namespace std; stack<char> opStack; // 全局运算符栈,保证状态持续 // 修正优先级规则:乘除%优先级 > 加减,左括号优先级最低 int priority(char op) { if (op == '+' || op == '-') return 1; if (op == '*' || op == '/' || op == '%') return 2; if (op == '(') return 0; return -1; } // 处理单个字符的逻辑 void processChar(char c) { if (isdigit(c)) { cout << c; // 数字直接输出到后缀表达式 } else if (c == '(') { opStack.push(c); // 左括号直接入栈 } else if (c == ')') { // 弹出栈中元素直到遇到左括号 while (!opStack.empty() && opStack.top() != '(') { cout << opStack.top(); opStack.pop(); } opStack.pop(); // 弹出左括号,不输出到结果 } else { // 处理运算符 // 循环弹出栈中优先级 >= 当前运算符的元素 while (!opStack.empty() && priority(opStack.top()) >= priority(c)) { cout << opStack.top(); opStack.pop(); } opStack.push(c); // 当前运算符入栈 } } int main() { string expr; cout << "输入中缀表达式: "; cin >> expr; // 循环扫描表达式的每个字符 for (char c : expr) { processChar(c); } // 弹出栈中剩余的所有运算符 while (!opStack.empty()) { cout << opStack.top(); opStack.pop(); } cout << endl; return 0; }
关键逻辑说明
- 循环扫描:通过
for (char c : expr)遍历字符串的每个字符,逐个调用处理函数,完美覆盖所有输入字符。 - 栈的作用域:全局栈
opStack确保在整个表达式处理过程中保存运算符状态,不会每次调用函数都重置。 - 运算符处理:严格遵循中缀转后缀的算法规则,循环弹出高优先级运算符,保证后缀表达式的正确性。
- 收尾处理:表达式扫描完成后,弹出栈中剩余的所有运算符,确保结果完整。
内容的提问来源于stack exchange,提问作者Fajer
相关产品推荐
相关产品推荐

