使用栈完成中缀表达式转后缀表达式

后缀表达式也称为逆波兰表达式。求后缀表达式的过程有很多种,这里给出利用栈实现的过程。

现代编译器不会直接将算术表达式转化成机器层的代码。而是使用一个中间形式,成为后缀表达法。在后缀表达式中,运算符紧随在它的操作数的后面,例如,给出中缀表达式a+b它的后缀形式就是ab+,对于a+b*c,后缀形式就是abc*+,说白了就是表达式树的后序遍历。有了后缀表达式可以很容易的进行表达式求值。上面的例子中计算的过程就是遍历后缀表达式,遇到操作数就入栈(计算过程还是需要用到栈),遇到操作符就弹出两个操作数进行运算,然后将结果压栈,遍历完成后栈中的既是表达式值。

具体过程:

先将中缀表达式看成一个字符串,遍历中缀表达式,遇到一个操作符将它压栈,遇到操作数就加到后缀表达式中。举例说明:a-b+c*d

首先遇到的是一个a,然后将a加入后缀表达式中,然后遇到一个-(操作符)将它压栈,然后是一个b,将b加入到后缀表达式中,现在的后缀表达式是ab,栈中的操作符是-。

当遇到+号时,因为优先级相同,所以进行的操作是将-号出栈,并加入后缀表达式中,+号入栈。此时的后缀表达式为ab-,栈中保存的是+。

然后是c,加入到后缀表达式中,现在的后缀表达式是ab-c。然后遇到*,因为*的优先级比+高,所以将*入栈。

然后是d,将d加入后缀表达式,此时的枚举完成,之后只需要将栈中的操作符出栈依次加入到后缀表达式中即可。

得到的后缀表达式就是ab-cd*+。

进出栈的规则就是对中缀字符串的每个运算符。栈为空,操作符入栈。栈不空,如果此时栈顶元素优先级比中缀表达式中的低,将该运算符压栈,否则,将运算符出栈加入到后缀表达式中,将该运算符入栈。

对于有括号的表达式,在中缀字符串遇到一个左括号时,无条件入栈,但是它的优先级最低,然后在中缀表达式中遇到一个右括号时,一直弹出栈中的操作符,直到遇到一个左括号为止。例如:x-(y*a/b-(z+d*e)+c)/f。

将x加入后缀表达式。后缀表达式为x,栈空。

将-号入栈。后缀表达式为x,栈为-。

遇到一个左括号,将左括号入栈。后缀表达式为x,栈为-(。

y加入后缀表达式。后缀表达式为xy,栈为-(。

将*入栈。后缀表达式为xy,栈为-(*。

a加入后缀表达式。后缀表达式为xya,栈为-(*。

遇到一个/号,将*号出栈加入到后缀表达式中,然后将/入栈。后缀表达式为xya*,栈为-(/。

将b加入后缀表达式。后缀表达式为xya*b,栈为-(/。

遇到一个-号,将/出栈加入到后缀表达式,然后将-入栈。后缀表达式为xya*b/,栈为-(-。

遇到左括号,入栈。后缀表达式为xya*b/,栈为-(-(。

将z加入后缀表达式。后缀表达式为xya*b/z,栈为-(-(。

将+入栈。后缀表达式为xya*b/z,栈为-(-(+。

将d加入后缀表达式。后缀表达式为xya*b/zd,栈为-(-(+。

将*入栈。后缀表达式为xya*b/zd,栈为-(-(+*。

将e加入到后缀表达式。后缀表达式为xya*b/zde,栈为-(-(+*。

遇到一个右括号。将操作符弹出栈,直到遇到左括号。后缀表达式为xya*b/zde*+,栈为-(-。

遇到一个+号。弹出-号加入后缀表达式,将+号入栈。后缀表达式为xya*b/zde*+-,栈为-(+。

将c加入后缀表达式。后缀表达式为xya*b/zde*+-c,栈为-(+。

遇到一个右括号。将操作符弹出栈,直到遇到左括号。后缀表达式为xya*b/zde*+-c+,栈为-。

将/入栈。后缀表达式为xya*b/zde*+-c+,栈为-/。

然后将f加入后缀表达式,操作符弹出栈。得到的后缀表达式为xya*b/zde*+-c+f/-。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值