前序、中序、后序表达式的相互转换问题

这是一个常考的问题,现在总结一下:

一、前序表达式转换为中序表达式:

从右往左开始,取出一个操作符和操作符右边的两个数进行计算,并将计算的结果放过去,直到计算结束。以前序表达式“+/*23-21*3-41”为例,将其转换为中序表达式:

(1)取出“-”、4、1,计算并将结果放回得到“+/*23-21*3(4-1)”;

(2)取出“*”、3、(4-1),计算并将结果放回得到“+/*23-21(3*(4-1))”;

(3)取出"-"、2、1,计算并将结果放回得到"+/*23(2-1)(3*(4-1))";

(3)取出"*"、2、3,计算并将结果放回得到“+/(2*3)(2-1)(3*(4-1))”;

(4)取出"/"、(2*3)、(2-1),计算并将结果放回得到“+((2*3)/(2-1))(3*(4-1))”;

(5)取出“+”、((2*3)/(2-1))、(3*(4-1)),计算将结果放回得到“((2*3)/(2-1))+(3*(4-1))”,计算结束,显然计算结果为15;

二、后序表达式转换为中序表达式:

从左向右开始,取出一个操作符和操作符左边的两个数进行计算,并将计算的结果放过去,直到计算结束,以后序表达式“ab+cde+**”为例,将其转换为中序表达式:

(1)取出“+”、a、b,计算并将结果放回得到“(a+b)cde+**”;

(2)取出"+"、d、e,计算并将结果放回得到"(a+b)c(d+e)**";

(3)取出“*”、c、(d+e),计算并将结果放回得到“(a+b)(c*(d+e))*”;

(4)取出"*"、(a+b)、(c*(d+e)),计算并将结果放回得到"(a+b)*(c*(d+e))";显然,计算结束

三、中序表达式转换为后序表达式:

这个有点复杂,我们假设中序表达式中只有+、*、(、),将中序表达式 a+b*c+(d*e+f)*g,转换为后序表达式:abc*+de*f+g*+,转换过程需要借助一个辅助栈,转换的规则是这样的:

从左向右扫描,遇到操作数,则直接输出;当遇到操作符(+、-、*)和左括号时,则从栈中弹出栈元素并写到输出直到发现优先级(+优先级最低,左括号优先级最高)更低的元素为止(注意,不弹出这个优先级更低的元素),但是有一个例外,即除非在处理右括号的时候,否则我们绝不从栈中弹出左括号,当从栈弹出元素的工作完成后,再将当操作符压入栈中;当遇到右括号的时候,则将栈中元素弹出并写入到输出直到遇到一个左括号,但是这个左括号只是被弹出,并没有写到输出中。如果从左向右扫描结束,栈中还有元素,则将栈中元素弹出并写到输出,直到栈为空。

现在我们按照上述规则,来转换前面提到的那个中序表达式,将其转换我后序表达式:

(1)取到运算数a,直接输出,则,栈为空,输出为a;

(2)取到运算符+,直接入栈,则,栈为+,输出未a;

(3)取出运算数b,直接输出,则,栈为+,输出为ab;

(4)取出运算符*,则,按照规则,先从栈中弹出元素直到遇到比 * 优先级更低的元素为止但不弹出这个更低的元素,最后在把* 入栈,因为此时栈中只有+,且+就是比*优先级更低的元素且此优先级更低的元素+并不弹出,所以*入栈,则,栈为*+,输出为ab;

(5)取出运算数c,直接输出,则,栈为*+,输出我abc;

(6)取出运算符+,则, 按照规则,先从栈中弹出元素直到遇到比+ 优先级更低的元素为止但不弹出这个更低的元素,最后在把+ 入栈,此时栈中有*+,*比+优先级高则弹出并写到输出中,输出为abc*,栈为+,但是栈中的+不是比运算符+优先级更低的元素,所以继续弹出+并写到输出,则输出为abc*+,栈为空,不弹了,最后将运算符+入栈,则栈为+,输出为abc*+;

(7)取出左括号(,则,按照规则,先从栈中弹出元素直到遇到比(  优先级更低的元素为止但不弹出这个更低的元素,最后在把 ( 入栈,此时栈中有+,且优先级比 (低,则将 ( 入栈即可,则,栈为( + ,输出为abc*+;

(8)取出运算数d,直接输出,则,栈为(+,输出为abc*+d;

(9)取出运算符*,则按照规则(那个例外),直接将*入栈,则,栈为*(+,输出为abc*+d;

(10)取出运算数e,直接输出,则,栈为*(+,输出为abc*+de;

(11)取出运算符+,按照规则,我们弹出栈中的*到输出,并将+入栈,则栈为+(+,输出为abc*+de*;

(12)取出运算数f,直接输出,则,栈为+(+,输出为abc*+de*f;

(13)取出右括号),按照规则,弹出栈中元素并写到输出直到左括号(且不输出(,则栈为+,输出为abc*+de*f+;

(14)取出运算符*,按照规则,栈中元素+已经是比*优先级小了,我们将*入栈,则栈为*+,输出为abc*+de*f+;

(15)取出运算数g,直接输出,则栈为*+,输出为abc*+de*f+g;

(16)中序表达式扫描结束,将栈中剩余的元素弹出并写到输出,则栈为空,输出为abc*+de*f+g*+;处理结束

四、中序表达式转换为前序表达式

这个比较复杂,以中序表达式 2*3/(2-1)+3*(4-1)为例,转换规则如下

1、反转表达式,让它逆序排列,如2*3/(2-1)+3*(4-1),反转后为)1-4(*3+)1-2(/3*2

2、从字符串中取出下一个字符并处理:

2.1、如果是操作数,则直接输出

2.2、如果是),则压入栈中

2.3、如果是运算符,但不是( 也不是 ),则不断进行如下处理

2.3.1、如果栈为空,则此运算符入栈,结束此步骤

2.3.2、如果栈顶为),则此运算符入栈,结束此步骤

2.3.3、如果此运算符与栈顶元素优先级相同或更高,则此运算符入栈,结束此步骤。

2.3.4、否则,执行连续的出栈操作,知道满足上述三个条件之一,结束此步骤

2.4、如果是(,执行连续的出栈操作,直到遇见)为止,并将)出栈且丢弃之

3、如果有更多的字符,则转到第2步

4、字符处理完毕,则执行连续的出栈操作,直到栈为空

5、再次反转表达式,得到最终的结果。


通过上述步骤,中序表达式2*3/(2-1)+3*(4-1)转换为前序表达式的结果为+/*23-21*3-41。


五、前序表达式转换为后序表达式:

这个,我还不知道怎样直接转换,但是可以先把前转换为中,再把中转换成后。。。。

六、后序表达式转换为前序表达式:

这个,我还不知道怎样直接转换,但是可以先把转换为中,再把中转换成。。。。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值