leetcode刷题-题目2 :逆波兰式-扩展

接上篇,我们可以知道逆波兰式的计算很容易,但是一般情况表达式都是中序表达式(就是运算符在操作数中间),一个问题油然而生:

如何才能将一个中序的表达式变成逆波兰式呢?


考虑这样一个例子:3*(2-7)+5/(6+9)

观察可得计算中序算式要考虑运算符的优先级,从而确定不同表达式的求值顺序。+-优先级小于*/的优先级,括号内表达式计算优先级高于括号

外表达式。

例1:3*4-1。

我们知道逆波兰式计算的时候操作符和操作数紧挨的首先计算。所以在转换过程中,中序算式中最先计算的表达式应该被紧凑放置。

例1中3*4最先计算,所以我们把他们放到一起,得到乘积之后再和1做减法,所以逆波兰式为34*1-。

在复杂一点例如5-2*7+1:最先计算应为2*7,之后进行加法和减法运算,所以逆波兰可以表示为:527*-1+或者527*1-+。以上两种逆波兰计算结果一致。

归纳一下,可以得到中序算式转换逆波兰式的思路:

1 如果当前中序表达式只剩一个元素x,返回之。

2 找出表达式中优先级最高的表达式(如果有多个同等优先级的表达式,取最左边的优先),转换成逆波兰式:

转换方式为:a+b -> ab+

    a-b  -> ab-

    a*b  -> ab*

                      a/b  -> ab/

转换后的逆波兰式 付给变量x。代入并替换原来的表达式。

         3 递归(循环)回第一步。

怎么样上面的算法是不是看起来还不错~

算法有了实现方式就很多了,可以递归的方式,也可以使用循环,这里假设中序表达式是以一个列表的方式输入的,

进一步观察我们还可以得到下面的结论:

1 如果乘/除表达式在加/减表达式左边,我们可以直接将乘/除表达式变为逆波兰式。

2 括号内的表达式优先级最高,所以如果碰到括号表达式,首先对括号内的表达式进行逆波兰转换。


根据上面的特性我们可以一次遍历中序表达式得到逆波兰式,而非上面算法的循环或者递归的方式。

算法如下:

      扫描当前输入,如果是操作数,入逆波兰列表

      如果是操作符,入操作符处理流程:

1 使用栈保存之前处理的操作符

2 :

1) 如果当前算符优先级小于栈顶保存算符优先级,且当前算符不为‘)’,栈顶算符入逆波兰列表。否则到3)

2) 回到1 

3) 当前操作符入栈。

1)如果当前操作符为')',且栈顶为‘(’,pop栈顶元素,丢弃当前操作符。

2) 当前操作符入栈,

4) 扫描下一个元素,若输入为空,返回逆波兰列表作为结果,否则转1)



算符优先级排列如下')' ,‘(’(栈顶), ' + ' = ' - '  , < ' * ' = ' / ' <  ' ( '(当前)

注意符号'('作为当前算符和栈顶算符的优先级别是不一样的。



      




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值