Appearance
题目
已知操作符包括 +、−、∗、/、( 和 )。将中缀表达式 a+b−a∗((c+d)/e−f)+g 转换为等价的后缀表达式 ab+acd+e/f−∗−g+ 时,用栈来存放暂时还不能确定运算次序的操作符,若栈初始为空,则转换过程中同时保存在栈中的操作符的最大个数是( )。
错因
B
可能把"出现过"和"同时存在"混了。整个转换过程中累计入过栈的运算符确实多于 5 个(每个 + − * / 都进过),但题目问"同时存在于栈中的最大数量"。每当遇到 ) 或低优先级运算符就会弹栈,所以瞬时最大数 5 ≠ 累计入栈数 7。
C
更进一步把表达式中的所有运算符(共 8 个:+ − * + − / − +)当成最大栈深度。同样错在没区分"累计 vs 瞬时"——栈中元素是动态出入,不是只进不出。
D
把整个表达式的总字符数(11 个:a+b−a*((c+d)/e−f)+g 去字母剩下的运算符 + 括号)当答案。彻底忘了"操作数(a, b, c...)不进操作符栈"。
总解析
中缀转后缀的栈算法核心规则:
- 遇到操作数(字母):直接输出,不进栈
- 遇到
(:直接入栈 - 遇到
):弹栈直到遇到(,丢弃( - 遇到运算符 op:弹出栈顶所有优先级 ≥ op 的运算符(注意
(不算),然后 op 入栈
逐字符跟踪 a+b−a∗((c+d)/e−f)+g:
| 步骤 | 读到 | 栈(栈底→栈顶) | 输出 |
|---|---|---|---|
| 1 | a | 空 | a |
| 2 | + | + | a |
| 3 | b | + | ab |
| 4 | − | − | ab+(弹 +) |
| 5 | a | − | ab+a |
| 6 | * | −* | ab+a |
| 7 | ( | −*( | ab+a |
| 8 | ( | −*(( | ab+a |
| 9 | c | −*(( | ab+ac |
| 10 | + | −*((+ | ab+ac ← 栈深 5(最大) |
| 11 | d | −*((+ | ab+acd |
| 12 | ) | −*( | ab+acd+(弹到 () |
| 13 | / | −*(/ | ab+acd+ |
| 14 | e | −*(/ | ab+acd+e |
| 15 | − | −*(− | ab+acd+e/(弹 /) |
| 16 | f | −*(− | ab+acd+e/f |
| 17 | ) | −* | ab+acd+e/f− |
| 18 | + | + | ab+acd+e/f−*−(弹 *、−) |
| 19 | g | + | ab+acd+e/f−*−g |
| 20 | 末尾 | 空 | ab+acd+e/f−*−g+ |
栈深度的最大值在第 10 步 −*((+,5 个运算符同时存在。
最终答案是 A(5)。