0715学习日志:算法之逆波兰表达式

一、栈的表达式

栈的三种表达式分别是:前缀、中缀和后缀。

注意事项:栈顶元素是最后被插入和最早被删除的元素。

二、前缀表达式

前缀表达式也称波兰表达式,就是所有运算符都在操作数前面。它的求值过程:计算机从右往左扫描,遇到数字就把数字压入数栈;遇到符号,就弹出数栈中的栈顶和次顶的两个数字和符号进行运算,把计算的结果压入栈中。

例: (3+4)*5-2的前缀表达式为  - * + 3 4 5 2

  1. 从右往左扫描,把数字2 5 4 3依次压入数栈;
  2. 遇到符号 + ,就弹出数栈中栈顶和次顶的两个数字(3、4)和符号(+)进行运算  ====>  3+4=7;   7压入栈中,数栈:7 5 2
  3. 继续向左扫描,遇到*,弹出7和5运算,7*5=35, 压入栈中。 35  2
  4. 遇到符号 - ,弹出35和2运算,35-2=33 。

三、中缀表达式

中缀表达式就是常见的运算表达式,需要比较运算符的优先级,对于人脑来说比较好比较,但是对于计算机来说是比较难算的。

四、后缀表达式

后缀表达式又叫逆波兰表达式,就是运算符在操作数后面。

例如(3+4)*5-2的后缀表达式为3 4 + 5 *2- , 计算机从左往右扫描, 遇到数字3和4,将数字3和4压入数栈,继续扫描。遇到符号+,就弹出数栈中栈顶和次顶的两个数字和符号进行运算  ===> 4+3 = 7; 7压入栈中,数栈 7 ;继续扫描遇到数字5,压入栈中,数栈5 7;继续扫描遇到*,弹出7、5进行运算,7*5=35;数栈35;继续扫描遇到2压入数栈,数栈2 35;继续遇到-,弹出35和2进行运算 ===> 35-2 =33。

五、带括号的中缀表达式的转换(详细步骤配图)

把带括号的中缀表达式转换为后缀表达式:9/(3+2)-6*(3-2)

转换规则:

首先需要分配2个栈,一个作为临时存储运算符的栈S1(含一个结束符号),一个作为存放结果(逆波兰式)的栈S2(空栈),S1栈可先放入优先级最低的运算符#,中缀式应以此最低优先级的运算符结束。可指定其他字符,不一定非#不可。从中缀式的左端开始取字符,逐序进行如下步骤:

(1)若取出的字符是操作数 ( 9, 3,2,6,3,2 ),则分析出完整的运算数,该操作数直接送入S2栈。

(2)若取出的字符是运算符  ( * / - +),则将该运算符与S1栈栈顶元素比较,如果该运算符(不包括括号运算符)优先级高于S1栈栈顶运算符(包括左括号)优先级,则将该运算符进S1栈,否则,将S1栈的栈顶运算符弹出,送入S2栈中,直至S1栈栈顶运算符(包括左括号)低于(不包括等于)该运算符优先级时停止弹出运算符,最后将该运算符送入S1栈。

(3)若取出的字符是“(”,则直接送入S1栈顶。

(4)若取出的字符是“)”,则将距离S1栈栈顶最近的“(”之间的运算符,逐个出栈,依次送入S2栈,此时抛弃“(”。

(5)重复上面的1~4步,直至处理完所有的输入字符。

(6)若取出的字符是“#”,则将S1栈内所有运算符(不包括“#”),逐个出栈,依次送入S2栈。

如果表达式结束,但栈中还有元素,将所有元素出栈,添加到后缀表达式中。

例如:9/(3+2)-6*(3-2)

1、分配两个栈,s1栈可放入#(优先级最低的运算符),s2栈暂时为空。

2、从左往右扫描,遇见操作数9,直接送入栈,如下图(左为s1,右为s2)

  

 3、 继续扫描,遇见/,且其优先级比#高,则送入s1栈。

  4、 继续扫描,遇见(,直接送入s1栈。

 5、继续扫描,操作数3直接入s2栈。

 6、 继续扫描,+与s1栈顶元素(比较,+优先级高,把+送入s1栈。

  7、 继续扫描,操作数2直接入s2栈。

  8、 继续扫描遇),将距离s1栈栈顶最近的至”(”之间的运算符逐个出栈,依次送入s2栈,”(”不需要送入。

 9、 继续扫描至 - ,与/比较,比/运算优先级低,将s1的栈顶元素入s2栈。

 10、继续扫描至6,入s2栈。

 11、 继续扫描遇 *,与s1栈顶运算符比,*高,压入s1栈。

12、 继续扫描遇(,入s1栈。

 13、 继续扫描至3,入s2栈。

 14、 继续扫描遇- ,与s1栈顶运算符比,-高,压入s1栈。

 15、 继续扫描,操作数2入s2栈。

 16、 继续遇),将距离s1栈栈顶最近的至”(”之间的运算符逐个出栈,依次送入s2栈,”(”不需要送入。

 

 17、 表达式结束但s1栈中还有元素,将所有元素取出添加到s2中。

 

 所以,9/(3+2)-6*(3-2)的后缀表达式为932+/632-*-

 学习日志如有错误,还望指正,多谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值