【数据结构】栈的应用:表达式求值(后缀表达式)

考点频率 :★★★★★(栈的核心应用,选择题必考,下午题偶尔结合考查)

难度 :⭐⭐⭐⭐

建议:重点掌握中缀转后缀的规则、后缀表达式的手工计算方法,这是下午题的隐性考点

1️⃣ 为什么需要后缀表达式?

你平时写的算式是 (3 + 4) × 5 - 6,这叫中缀表达式------运算符在操作数中间。人看得很舒服,但计算机处理起来很麻烦,因为要考虑括号和运算符优先级。

为了让计算机更方便计算,人们设计了两种替代格式:

  • 后缀表达式(逆波兰表达式) :运算符在操作数后面 。例如 3 4 + 5 × 6 -
  • 前缀表达式(波兰表达式) :运算符在操作数前面 。例如 - × + 3 4 5 6

后缀表达式的最大优点不需要括号,不需要考虑优先级,按顺序扫描即可计算。

2️⃣ 中缀表达式 → 后缀表达式(手工转换方法)

2.1 方法一:加括号法(适合手工计算)

操作步骤

  1. 按运算符优先级给表达式加括号(每个运算符对应一对括号)
  2. 将每个运算符移到它对应的右括号后面
  3. 去掉所有括号

示例 :将 (3 + 4) × 5 - 6 转为后缀表达式

复制代码
第1步:加括号
((3 + 4) × 5) - 6
  ↓ 每个运算符对应一对括号:
((3 + 4) × 5) - 6  →  (((3 + 4) × 5) - 6)
  最内层:3 + 4 → (3 4 +)
  再外层:× 5 → ((3 4 +) 5 ×)
  最外层:- 6 → (((3 4 +) 5 ×) 6 -)

第2步:去掉括号 → 3 4 + 5 × 6 -

2.2 方法二:符号栈法(理解计算机是怎么做的)

中缀转后缀(计算机实现):遍历中缀表达式的每个 token(操作数或运算符),按规则处理:

  1. 操作数:直接输出到后缀表达式
  2. 左括号 (:直接入栈
  3. 右括号 ):不断弹出栈顶运算符并输出,直到遇到左括号(左括号弹出但不输出)
  4. 运算符:当栈顶运算符的优先级 ≥ 当前运算符优先级时,弹出并输出栈顶,然后将当前运算符入栈

示例3 + 4 × 5 - 6

步骤 符号 输出(后缀) 运算符栈 说明
1 3 3 操作数直接输出
2 + 3 + 栈空,直接入栈
3 4 3 4 + 操作数直接输出
4 × 3 4 + × 栈顶 + 优先级低于 ×,直接入栈
5 5 3 4 5 + × 操作数直接输出
6 - 3 4 5 × + × 优先级 ≥ -,弹出 ×+ 优先级 ≥ -,弹出 +;然后 - 入栈
7 6 3 4 5 × 6 - 操作数直接输出
8 结束 3 4 5 × 6 - 弹出栈中剩余运算符

结果3 4 5 × 6 -

3️⃣ 后缀表达式的计算

计算规则

  1. 从左到右扫描后缀表达式
  2. 遇到操作数,入栈
  3. 遇到运算符,弹出栈顶的两个操作数,计算结果后入栈
  4. 扫描结束后,栈顶就是最终结果

示例 :计算 3 4 5 × 6 -

步骤 扫描到 操作
1 3 入栈 [3]
2 4 入栈 [3, 4]
3 5 入栈 [3, 4, 5]
4 × 弹出 4 和 5 → 4×5=20 → 入栈 [3, 20]
5 6 入栈 [3, 20, 6]
6 - 弹出 20 和 6 → 20-6=14 → 入栈 [3, 14]
7 结束 弹出栈顶 14

结果14(与原中缀表达式 (3+4)×5-6=35-6=29 不一致?等等,这里有问题!)

⚠️ 发现错误 :上面的计算结果是 14,但原式 (3+4)×5-6 应该等于 29。

原因 :我把运算符优先级搞反了。3 + 4 × 5 - 6 正确的后缀是 3 4 5 × + 6 -,而不是 3 4 5 × 6 -

修正后的计算

步骤 扫描到
1 3 [3]
2 4 [3, 4]
3 5 [3, 4, 5]
4 × [3, 20]
5 + [23]
6 6 [23, 6]
7 - [17]

结果 17 仍然不对?等等,原式 3+4×5-6 按乘除优先是 3+20-6=17,正确!我本来想写的是 (3+4)×5-6,但写成 3+4×5-6 了。

所以:(3+4)×5-6 对应的后缀是 3 4 + 5 × 6 -,计算如下:

步骤
3 [3]
4 [3, 4]
+ [7]
5 [7, 5]
× [35]
6 [35, 6]
- [29]

结果:29 ✅

4️⃣ 中缀 → 后缀 → 求值(完整例题)

题目 :计算中缀表达式 8 + (3 - 1) × 2

第1步:中缀 → 后缀

  • 加括号法:8 + ((3 - 1) × 2)(8 ((3 1 -) 2 ×) +) → 去掉括号:8 3 1 - 2 × +

第2步:计算后缀 8 3 1 - 2 × +

步骤 扫描到
1 8 [8]
2 3 [8, 3]
3 1 [8, 3, 1]
4 - [8, 2]
5 2 [8, 2, 2]
6 × [8, 4]
7 + [12]

结果:12 ✅

5️⃣ 运算符优先级速查

运算符 优先级
( ) 最高(用于改变运算顺序)
× /
+ -

6️⃣ 经典例题

例题1 (中缀转后缀):中缀表达式 a + b * c - d / e 对应的后缀表达式是( )。

A. a b c * + d e / -

B. a b c * d e / - +

C. a b * c + d e / -

D. a b c * + d e - /

解析a + b × c - d / ea (b c ×) + (d e /) -a b c × + d e / -。选 A


例题2 (后缀求值):后缀表达式 5 1 2 + 4 × + 3 - 的值为( )。

解析

步骤
5 [5]
1 [5, 1]
2 [5, 1, 2]
+ [5, 3]
4 [5, 3, 4]
× [5, 12]
+ [17]
3 [17, 3]
- [14]

答案:14

7️⃣ 记忆口诀

中缀转后缀,操作数直接写。

左括号入栈,右括号弹到底。

运算符看栈顶,同级高先弹。

后缀求值用栈,数字入栈运算符弹两数。

8️⃣ 小测验(评论区对答案)

中缀表达式 (a + b) * (c - d) 对应的后缀表达式是( )。

A. a b + c d - *

B. a b c d + - *

C. a b + c - d *

D. a b c + d - *

答案下期公布。

🔔 本专栏日更,点击头像 → 专栏《软考中级高频考点》订阅,第一时间接收新内容

#软考中级 #软件设计师 #栈 #后缀表达式 #表达式求值 #数据结构 #软考备考

相关推荐
szephyr1 小时前
腾讯云 ADP 智能体的 Skills 版本回滚总是回到旧配置,是缓存没清还是版本管理没开?
java·缓存·腾讯云
云烟成雨TD1 小时前
Micrometer 系列【39】链路追踪:入门案例 | 环境准备
java·云原生·链路追踪
HiDev_1 小时前
【非标自动化】plc执行顺序问题、扫描周期问题
深度学习·算法·机器学习
chuan.bai1 小时前
Java RAG 实战(第 3 篇):从交互式聊天到多轮上下文
java·人工智能·macos·ai
952361 小时前
Sentinel
java·后端·spring·sentinel·springcloud
阿pin1 小时前
Java随笔-JDK7 HashMap头插法为何能导致死循环?
java·开发语言·hashmap
高洁012 小时前
工信部教考中心证书-人工智能系列本系列
人工智能·python·深度学习·算法
陈王卜2 小时前
Reduce 算子优化笔记
算法
wabs6662 小时前
关于图论【最短路径之Bellman_ford 算法(判断负权回路)|卡码网95.城市间货物运输II的思考】
数据结构·算法·图论·bellman_ford算法·卡码网·判断负权回路