中序转后序的算法

平常所使用的表达式,主要是将操作数放在运操作数的两旁,例如a+b/d这样的式子,这称之为中序(Infix)表示式,对于人类来说,这样的式子很容易理解,但由于计算机执行指令时是有顺序的,遇到中序表示式时,无法直接进行运算,而必须进一步判断运算的先后顺序,所以必须将中序表示式转换为另一种表示方法。

可以将中序表示式转换为后序(Postfix)表示式,后序表示式又称之为逆向波兰表示式(Reverse polish notation),它是由波兰的数学家卢卡谢维奇提出,例如(a+b)*(c+d)这个式子,表示为后序表示式时是ab+cd+*。

用手算的方式来计算后序式相当的简单,将运算子两旁的操作数依先后顺序全括号起来,然后将所有的右括号取代为左边最接近的运算子(从最内层括号开始),最后去掉所有的左括号就可以完成后序表示式,例如:

a+b*d+c/d   =>    ((a+(b*d))+(c/d)) -> abd*+cd/+

如果要用程序来进行中序转后序,则必须使用堆栈,算法很简单,直接叙述的话就是使用循环,取出中序式的字符,遇操作数直接输出;堆栈运算子与左括号;堆栈中运算子优先级大于读入的运算子优先级的话,直接输出堆栈中的运算子,再将读入的运算子置入堆栈;遇右括号输出堆栈中的运算子至左括号。

例如(a+b)*(c+d)这个式子,依算法的输出过程如下:

image

Python代码:

def priority(op):

    if op in ['+', '-']:

        return 1

    elif op in ['*', '/']:

        return 2

    else:

        return 0



def toPostfix(infix):

    stack = ['']

    buffer = []

    for c in infix:

        if c == '(':

            stack.append(c)

        elif c in "+-*/":

            while priority(stack[-1]) >= priority(c):

                buffer.append(stack.pop())

            stack.append(c)

        elif c == ')':

            while stack[-1] != '(' && stack[-1] != '':

                buffer.append(stack.pop())

            stack.pop()

        else:

            buffer.append(c)

    while stack[-1] != '':

        buffer.append(stack.pop())

    return buffer



infix = "(a+b)*(c+d)"

print(toPostfix(infix))

print(toPrefix(infix))

你可能感兴趣的:(算法)