逆波兰表达式

这段时间在做关于计算字符串表达式方面的内容,开始接触逆波兰表达式,发现挺有意思的,就写下这篇文章以作记忆:

它的优势在于只用两种简单操作,入栈和出栈就可以搞定任何普通表达式的运算。其运算方式如下: 按顺序扫描逆波兰表达式,如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。这个过程正好符合了计算机计算的原理,所以,逆波兰式非常适宜计算机的处理。
将普通表达式转换为逆波兰表达式需要先判断表达式的合法性,判断其合法性之后便可以按照下面的过程完成逆波兰表达式的转换:

1.首先把普通的表达式按照运算符分离出来放在一个集合E中,比如1+2*3 分离后集合里的元素就是 1 + 2 * 3 五个元素

2.再定义一个字符串链表reversePolishExpression(最好是字符串类型的集合,免得后面要转类型),主要是用来存放逆波兰表达式的,还有定义一个堆栈stackOperator(存储运算符用),最后从左到右遍历集合E中的元素

3.遍历E的规则如下:

   3.1如果该元素是数字,直接把它添加到集合R中

   3.2否则它肯定是运算符,那么再进行判断

        3.2.1如果该元素是左括号"(",或者当时栈为空,那么直接入栈

        3.2.2如果该元素是右括号")",则把栈内的运算符出栈并添加到字符串链表reversePolishExpression中,直到遇到第一个左括号结束

              (左括号也出栈但不添加到字符串链表reversePolishExpression)

        3.2.3 否则该元素是普通的运算符(也就是+-*/之类的),那么用该运算符和栈内的运算符号比较优先级(至于怎么比较它们的优

                先级,你可以定义一个函数,传一个运算符过去,返回一个int,int值越大优先级越高),如果该运算符的优先级比栈内的运

                算符优先级高 或者 栈为空,则直接入栈,否则把栈内的运算符出栈并添加到R中,再判断下个栈内的运算符优先级,直到遇

                栈内的运算符优先级<=该运算符或者栈为空时再把该运算符入栈

   3.3整个过程完成后,再把栈内的所有运算符出栈并添加到reversePolishExpression中

如:"5 + ((1 + 2) * 4) − 3",根据算法可以得出stackOperator及reversePolishExpression值的变化过程:

扫描     操作    stackOperator值          reversePolishExpression值           注释

5           输出               空                                  5                                        当前字符是数字直接输出该数字
+           入栈               +                                   5                                        栈顶元素为空,不用比较,入栈
(            入栈                (                                   5                                        当前运算符为'(',直接入栈
(            入栈                (  (                                5                                        当前运算符为'(',直接入栈
1           输出                (  (                                5 1                                     当前字符是数字直接输出该数字
+           入栈                (  ( +                             5  1                                    + 优先级< 栈顶元素 ( ,入栈
2           输出                (  ( +                             5  1  2                                当前字符是数字直接输出该数字
)            出栈                (                                    5   1  2  +                          出栈并顺序输出运算符直到遇到第一个'('
*           入栈                (  *                                 5   1  2  +                          * 优先级< 栈顶元素 ( ,入栈
4           输出                (  *                                5   1  2  +  4                      当前运算符为'(',直接入栈
)            输出                空                                 5   1  2  +  4  *                   出栈并顺序输出运算符直到遇到第一个'('
-            入栈                -                                   5   1  2  +  4  *                   栈顶元素为空,不用比较,入栈
3           输出                 -                                  5   1  2  +  4  *  3               当前字符是数字直接输出该数字
最后      输出                空                                 5   1  2  +  4  *  3  -           顺序出栈并输出运算符直到栈元素为空

可以看出最后的输出结果为:14

关于预处理问题:

分离普通表达式的时候,负号和减号是相同的,得把减号用其他符号代替,怎么判断是减号还是负号?这个徐奥解决,其实从右往左遍历,遇到"-"时再判断它的前一个符,如果是数字或者右括号,那么它就是减号,当遇到的是负号时,会遇到两种情况:

一种是负号“服务”一个元素,如1*-9,可以表示为1*(0-9);   

另一种是负号服务一个子表达式,如1*-(-(-(1+2))),可以表示为1*(0-(-(-(1+2))))


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值