数据结构(C语言版)严蔚敏->用栈求解表达式(中缀表达式后缀表达式)
Posted il_持之以恒_li
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构(C语言版)严蔚敏->用栈求解表达式(中缀表达式后缀表达式)相关的知识,希望对你有一定的参考价值。
通常我们看到的表达式应该都属于中缀表达式,比如这个中缀表达式:
((15/(7-(1+1)))3)-(2+(1+1))
但是在计算机中如果要计算这个表达式的值,却不是按照这个表达式来计算的,其中需要涉及到另外一种表达式,也就是所谓的后缀表达式(也称为逆波兰式),比如上述那个中缀表达式对应的后缀表达式为:
15 7 1 1 + - / 3 * 2 1 1 + + -
1. 后缀表达式的手算方法
- 确定中缀表达式中各个运算符的运算顺序(运算顺序不唯一)
- 选择下一个运算符,按照【左操作数 右操作数 运算符】的方式结合成一个新的操作数
- 如果还有运算符没有被处理,就继续2步操作
【注】:因为第1步中运算符的运算顺序不唯一,因此最后得到的后缀表达式也不是唯一的,为了确定后缀表达式的唯一性,通常使用“左优先”的原则,即
只要左边的运算符能先计算,就优先计算左边的运算符。
如上述中缀表达式转换成后缀表达式的步骤如下:
- 按照“左优先”原则确定中缀表达式各个运算符的运算顺序
如下:
- 按照第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. 中缀表达式的计算
- 需要用到两个栈(这里不讲用后缀表达式,如果直接使用后缀表达式,直接一个栈即可,如下),操作数栈和运算符栈;
- 若扫描到操作数,压入操作数栈中;
- 若扫描到运算符或界限符,则按照“中缀转后缀”相同逻辑压入运算符(期间也会弹出运算符,每当弹出一个运算符时,就需要再弹出两个操作数栈的栈顶元素并执行相应运算,运算结果再压回操作数栈)
以上是关于数据结构(C语言版)严蔚敏->用栈求解表达式(中缀表达式后缀表达式)的主要内容,如果未能解决你的问题,请参考以下文章
最详细数据结构(C语言版 第2版)课后习题答案全集 严蔚敏 等 编著