数据结构(C语言版)严蔚敏->用栈求解表达式(中缀表达式后缀表达式)

Posted 坚持不懈的大白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构(C语言版)严蔚敏->用栈求解表达式(中缀表达式后缀表达式)相关的知识,希望对你有一定的参考价值。

通常我们看到的表达式应该都属于中缀表达式,比如这个中缀表达式:
((15/(7-(1+1)))3)-(2+(1+1))
但是在计算机中如果要计算这个表达式的值,却不是按照这个表达式来计算的,其中需要涉及到另外一种表达式,也就是所谓的后缀表达式(也称为逆波兰式),比如上述那个中缀表达式对应的后缀表达式为:
15 7 1 1 + - / 3 * 2 1 1 + + -

1. 后缀表达式的手算方法

  1. 确定中缀表达式中各个运算符的运算顺序(运算顺序不唯一)
  2. 选择下一个运算符,按照【左操作数 右操作数 运算符】的方式结合成一个新的操作数
  3. 如果还有运算符没有被处理,就继续2步操作

【注】:因为第1步中运算符的运算顺序不唯一,因此最后得到的后缀表达式也不是唯一的,为了确定后缀表达式的唯一性,通常使用“左优先”的原则,即
只要左边的运算符能先计算,就优先计算左边的运算符。

如上述中缀表达式转换成后缀表达式的步骤如下:

  1. 按照“左优先”原则确定中缀表达式各个运算符的运算顺序
    如下:
  2. 按照第2步和第3步依次进行即可,如下:
1                  1 1 +
2                  7 1 1 + -
3                  15 7 1 1 + - /
4                  15 7 1 1 + - / 3 *
5                  1 1 +  
6                  2  1 1 + +
7                  15 7 1 1 + - / 3 * 2  1 1 + + -

2. 后缀表达式的机算实现

这个过程中需要用到栈,进行如下操作:
初始化一个栈,用于保存暂时还不能确定运算符顺序的运算符,从左到右处理各个元素,直到末尾可能遇到如下3中情况:
1. 遇到操作数,直接加入到后缀表达式中;
2.遇到界限符,遇到“(”直接入栈;遇到“)”则依次弹出栈内运算符并加入到后缀表达式,直到弹出“(”为止。注意:“(”不需要加入到后缀表达式中;
3. 遇到运算符,依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入到后缀表达式中,若碰到“(”或栈为空则停止。之后再把当前运算符入栈。


按照上述规则,可以得到 15 7 1 1 + - / 3 * 2 1 1 + + ,此时栈中还有一个 - 号没有添加到后缀表达式中,因此还需要对栈进行空栈判断,然后再出栈将相应运算符加入到后缀表达式中。(小编不知道怎么搞动画进行描述,所以只能自己做个草图哈,读者也可以自己试试)

3. 后缀表达式实现的参考代码

这个代码我写在博客园里,文章链接为:数据结构(C语言版)严蔚敏->链栈的定义、利用链栈将中缀表达式转换成后缀表达式

4. 中缀表达式的计算

  1. 需要用到两个栈(这里不讲用后缀表达式,如果直接使用后缀表达式,直接一个栈即可,如下),操作数栈和运算符栈;
  2. 若扫描到操作数,压入操作数栈中;
  3. 若扫描到运算符或界限符,则按照“中缀转后缀”相同逻辑压入运算符(期间也会弹出运算符,每当弹出一个运算符时,就需要再弹出两个操作数栈的栈顶元素并执行相应运算,运算结果再压回操作数栈)

以上是关于数据结构(C语言版)严蔚敏->用栈求解表达式(中缀表达式后缀表达式)的主要内容,如果未能解决你的问题,请参考以下文章

C语言 版 数据结构

数据结构笔记(C语言版)严蔚敏

最详细数据结构(C语言版 第2版)课后习题答案全集 严蔚敏 等 编著

3-5-表达式求值-栈和队列-第3章-《数据结构》课本源码-严蔚敏吴伟民版

清华大学严蔚敏数据结构题集完整答案(c语言版)

《数据结构-C语言版》(严蔚敏,吴伟民版)课本源码+习题集解析使用说明