龙空技术网

Python数据结构与算法07:基本结构:栈的应用之表达式转换(上)

挂可挂 8

前言:

目前各位老铁们对“表达式的转换”大概比较看重,我们都想要了解一些“表达式的转换”的相关资讯。那么小编在网上收集了一些关于“表达式的转换””的相关内容,希望你们能喜欢,大家快快来了解一下吧!

注:本文如涉及到代码,均经过Python 3.7实际运行检验,保证其严谨性。

本文阅读时间约为7分钟。


中缀表达式(infix expression)

给一个普通的表达式B*C,很容易知道其意思是B乘以C。

这种操作符(operator)介于操作数(operand)中间的表示法,称为“中缀”表示法。用中缀表示法的表达式称为中缀表达式。

类似于A+B*C这种,到底是先计算A+B还是先计算B*C?这是中缀表达式二义性的地方。

为了解决上述表达式的起义,人们引入了操作符的“优先级”这个概念。规定高优先级的操作符先操作,相同优先级的操作符从左到右依次操作。

除了优先级之外,又加入括号“()”表示强制优先级,括号的优先级最高;若括号有嵌套,则优先级从内到外是依次从高到低。

计算机处理表达式 上述处理表达式的方法是适用于人的,但计算机如何处理表达式呢? 对计算机来说,最好是能明确规定所有的计算顺序,这样无需处理复杂的优先规则。 在这样的诉求之下,引入了全括号表达式,在所有的表达式项两边都加上括号。比如A+B*C+D,用全括号表达式的形式表达就是((A+(B*C))+D)。

出来一个新的问题:可否将中缀表达式中的操作符的位置稍微移动一下?

这个新的问题,又引出了两个新的概念:前缀表达式和后缀表达式。


前缀表达式(prefix expression)和后缀表达式(postfix expression)

将中缀表达式A+B中的操作符“+”移动到前面或后面,形成新的表达式:

操作符移到前面,形成前缀表示法“+AB”;操作符移到后面,形成后缀表示法“AB+”。

所谓前缀和后缀,要看操作符相对操作数的位置:若操作符相对操作数在左边,则是前缀;若操作符相对操作数在右边,则是后缀。 比如中缀表达式(A + B) * C,变成前缀表达式就是* + A B C,变成后缀表达式就是A B + C*。(下划线是为了帮助理解)

前缀表达式和后缀表达式这两种表达式,相比于中缀表达式,必须的括号消失了。这是因为,在前缀和后缀表达式中,操作符的次序完全决定了运算的次序,不再有混淆。距离操作数越近的操作符的优先级越高。

这对计算机来说,是十分友好的。

计算机内部的表达式都避免采用复杂的中缀形式,而是采用前缀或后缀表达式,尤其是后缀表达式。


中缀表达式如何转换为前缀和后缀形式

步骤1:中缀表达式先转换为全括号的形式。

步骤2:如果把操作符移动右括号的位置,代替右括号,并删除对应的左括号,则正好把子表达式转换为后缀形式,进一步把更多的操作符移动到相应的右括号处代替之,同样再删去对应的左括号,那么整个表达式就完成了从中缀表达式到后缀表达式的转换。

同理,如果把操作符移动到左括号的位置代替左括号,并删除对应的右括号,也就完成了从中缀表达式到前缀表达式的转换。

由上述推论可以得知,无论一个中缀表达式多复杂,如果要把他们转换成前缀或者后缀表达式,只需要两个步骤:

1)将中缀表达式转换成全括号形式。

2)将所有的操作符移动到子表达式所在的左括号(前缀)或者右括号(后缀)处,代替之,再删除对应的右括号或者左括号即可得到对应的前缀表达式或后缀表达式。

拿A + B * C + D这个表达式来说:

先改为全括号形式:((A + (B * C)) + D)。

变为前缀表达式:((A + (B * C))) + D => ((A + * B C) + D) => (+ A * B C + D) => + + A * B C D。

变为后缀表达式:((A + (B * C)) + D) => ((A + B C *) + D) => (A B C * + + D) => A B C * + D +。


最后,用图示看一个较为复杂的例子:


一个复杂表达式转换的例子

To be continued.

标签: #表达式的转换