Appearance
题目
假设栈初始为空,将中缀表达式 a/b+(c*d-e*f)/g 转换为等价的后缀表达式的过程中,当扫描到 f 时,栈中的元素依次是( )。
错因
A
把第 9 步处理 - 时的"先弹 * 再入 -"颠倒成了"- 在 * 下面"。看到栈顶有 * 还没消,就以为 - 是夹在中间,写成 +(*-。实际上 - 是在 * 弹出后才入栈的,扫到 f 时 * 是新一轮(*f)的运算符,结构应是 +, (, -, *(* 在最顶)。
C
误以为 / 还在栈底。实际上当扫到 + 时,+ 优先级不高于栈顶 /,按规则 / 必须先弹出输出,然后 + 才入栈——所以从 + 入栈那一刻起,/ 已经离开栈了。栈中根本不会同时存在 / 和 +。
D
漏写了左括号 (。中缀转后缀算法里,( 是直接入栈的(不参与优先级比较),扫到 ) 才会被弹出。本题扫到 f 时还没扫到 ),( 当然还在栈里。
总解析
中缀转后缀算法(运算符栈)的核心规则:
- 操作数:直接输出
(:直接入栈):弹出运算符直到遇到(,然后丢弃这对括号- 普通运算符:与栈顶比较优先级——
- 若栈顶是
(或栈空:直接入栈 - 若当前优先级 > 栈顶:直接入栈
- 若当前优先级 ≤ 栈顶:循环弹出并输出栈顶,直到栈顶优先级 < 当前(或栈顶为
(/ 栈空),再入栈当前
- 若栈顶是
优先级:* / 高,+ - 低,( 不参与比较。
逐字符扫描 a/b+(c*d-e*f)/g:
| 步 | 当前 | 动作 | 栈(底→顶) | 后缀输出 |
|---|---|---|---|---|
| 1 | a | 输出 | (空) | a |
| 2 | / | 栈空,入栈 | / | a |
| 3 | b | 输出 | / | ab |
| 4 | + | + ≤ 栈顶 /:弹 / 输出,再入栈 + | + | ab/ |
| 5 | ( | 直接入栈 | + ( | ab/ |
| 6 | c | 输出 | + ( | ab/c |
| 7 | * | 栈顶是 (,直接入栈 | + ( * | ab/c |
| 8 | d | 输出 | + ( * | ab/cd |
| 9 | - | - ≤ 栈顶 *:弹 * 输出。栈顶变 (,停止弹出,入栈 - | + ( - | ab/cd* |
| 10 | e | 输出 | + ( - | ab/cd*e |
| 11 | * | * > 栈顶 -:直接入栈 | + ( - * | ab/cd*e |
| 12 | f | 扫到 f 这一刻——栈状态为 + ( - * | + ( - * | ab/cd*e |
栈中元素从底到顶:+, (, -, * —— 写作 +(-*。
关键判断点:
- 第 4 步证明
/不会和+共存(这是 C、D 选项的死结)- 第 9 步证明
*必须在-之上(这是 A 选项颠倒的地方)(一直存活到)出现(D 选项漏掉它就错了)
最终答案是 B(+(-*)。