栈的应用:将中缀表达式转为后缀表达式以及后缀表达式求值

前言

如果你不懂栈的操作;你可以看我的钱一篇博客栈(ADT)的定义以及基本操作(使用进制转化为例)

中缀表达式

是我们在数学里平常使用的算术表达式,如 (2 + 1) * 3;

后缀表达式

不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则);如:21 + 3 ;

如何将中缀表达式转换为后缀

我们从左到有读中缀表达式,如果读到的是操作数,立刻放到后缀表达式中;如果读到操作符,不立即放入结构体中,而是将其放入一个栈(操作符栈)中;
入栈规则

  1. 若为 ‘(’,入栈;
  2. 若为 ‘)’,则依次把栈中的的运算符加入后缀表达式中,直到出现’(’,从栈中删除’(’ (并不将’('放入后缀,而是删除!)
  3. 若为 除括号外的其他运算符, 当其优先级高于除’('以外的栈顶运算符时,直接入栈。否则从栈顶开始,依次弹出比当前处理的运算符优先级高和优先级相等的运算符,直到一个比它优先级低的或者遇到了一个左括号为止,然后将其自身压入栈中(先出后入)。
  4. 当扫描的中缀表达式结束时,栈中的的所有运算符出栈;

人工转化
第一步:按照运算符的优先级对所有的运算单位加括号;
第二步:转换后缀表达式;
后缀:把运算符号移动到对应的括号后面
把括号去掉:后缀式子出现
发现没有,后缀式是不需要用括号来进行优先级的确定的。如表达式:4 3 * 5 2 - / 6 +

步骤 表达式
0 4 * 3 / ( 5 / 2 ) + 6
1 ( ( ( 4 * 3 ) / ( 5 - 2 ) ) + 6 )
2 ( ( ( 4 3 * ) / ( 5 2 - ) ) + 6 )
3 ( ( ( 4 3 * ) ( 5 2 - ) / ) + 6 )
4 ( ( ( 4 3 * ) ( 5 2 - ) / ) 6 + )
5 4 3 * 5 2 - / 6 +

将以 a + b * c + ( d * e + f ) * g 为例;

转换结果为 a b c * + d e * f + g * +

  1. a被读入,放入后缀表达式;
操作符栈 后缀表达式
a
  1. '+'被读入,放入栈;
操作符栈 后缀表达式
+ a
  1. b被读入,放入后缀表达式;
操作符栈 后缀表达式
+ a b
  1. '*'被读入,操作符栈的栈顶元素‘+’比 ‘ * ’优先级低,所以‘ * ’进栈。
操作符栈 后缀表达式
+ * a b
  1. c被读入,放入后缀表达式;
操作符栈 后缀表达式
+ * a b c
  1. '+'被读入,可以发现‘+’的优先级低于‘ * ’,所以我们将‘ * ’从栈中弹出并放到后缀表达式中,接着,栈中就剩下‘+’,‘+’与现在被读入的操作符优先级相同,所以我们将‘+’从栈中弹出并放到后缀表达式中,最后,将刚刚遇到的‘+’放入栈中;
操作符栈 后缀表达式
+ a b c * +
  1. '('被读入,由于其有着最高的优先级,直接压入栈中;
操作符栈 后缀表达式
+ ( a b c * +
  1. d被读入,放入后缀表达式;
操作符栈 后缀表达式
+ ( a b c * + d
  1. '*'被读入,栈顶元素是‘(’,除非遇到右括号,否则左括号不会从栈中弹出,因此,我们将‘ * ’压入栈中;
操作符栈 后缀表达式
+ ( * a b c * + d
  1. e被读入,放入后缀表达式;
操作符栈 后缀表达式
+ ( * a b c * + d e
  1. '+'被读入,我们将‘ * ’弹出并放入后缀表达式,然后将‘+’压入栈中;
操作符栈 后缀表达式
+ ( + a b c * + d e *
  1. f被读入,放入后缀表达式;
操作符栈 后缀表达式
+ ( + a b c * + d e * f
  1. ')'被读入,我们将栈元素逐个弹出,直到遇到‘(’,最后将‘(’删除;
操作符栈 后缀表达式
+ a b c * + d e * f +
  1. '*'被读入,将其压入栈中;
操作符栈 后缀表达式
+ * a b c * + d e * f +
  1. g被读入,放入后缀表达式;
操作符栈 后缀表达式
+ * a b c * + d e * f + g
  1. 现在输入为空,因此我们将,栈中的符号逐一弹出,直到表达式为空;
操作符栈 后缀表达式
a b c * + d e * f + g * +

至此,转换成功;

如何计算后缀表达式的值

这里用后缀表达式 **6 5 2 3 + 8 * + 3 + ***来示例;
首先,将 6 5 2 3放入栈中:

栈顶元素 操作数栈
3 6 5 2 3

下面读到操作符‘+’,所以讲栈顶元素 3 弹出,接着再将栈顶元素2弹出;并计算 3 + 2 = 5的值后将5压入栈中;

栈顶元素 操作数栈
5 6 5 5

接着,8进栈;

栈顶元素 操作数栈
8 6 5 5 8

现在见到操作符‘*’,弹出5和8,计算5 * 8 = 40,并将40压入栈中;

栈顶元素 操作数栈
40 6 5 40

接着是‘+’号,弹出40和5,计算40 + 5 = 40,并将45压入栈中;,

栈顶元素 操作数栈
45 6 45

接着:是3,入栈;

栈顶元素 操作数栈
3 6 45 3

‘+’,弹出45和3,计算45 + 3 = 48,并将48压入栈中;,

栈顶元素 操作数栈
48 6 48

‘*’,弹出48和6,计算48 * 6 = 288,并将288压入栈中;

栈顶元素 操作数栈
288 288

最后结果是288;

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值