从中创建表达式树时是否有必要将中缀表示法转换为后缀?

时间:2017-03-05 16:05:22

标签: data-structures expression-trees postfix-notation infix-notation

我想创建一个以中缀形式给出表达式的表达式树。是否有必要先将表达式转换为postfix然后再创建树?我知道它在某种程度上取决于问题本身。但是假设它是数学函数的简单表达,具有未知数和运算符,如:/ * ^ + - 。

1 个答案:

答案 0 :(得分:2)

没有。如果您要构建表达式树,则不必先将表达式转换为postfix。在解析时构建表达式树会更简单。

我通常为表达式编写递归下降解析器。在这种情况下,每个递归调用只返回它解析的子表达式的树。如果你想使用迭代分流码式算法,那么你也可以这样做。

这是python中一个简单的递归下降解析器,它创建了一个带有元组节点的树:

import re

def toTree(infixStr):
    # divide string into tokens, and reverse so I can get them in order with pop()
    tokens = re.split(r' *([\+\-\*\^/]) *', infixStr)
    tokens = [t for t in reversed(tokens) if t!='']
    precs = {'+':0 , '-':0, '/':1, '*':1, '^':2}

    #convert infix expression tokens to a tree, processing only
    #operators above a given precedence
    def toTree2(tokens, minprec):
        node = tokens.pop()
        while len(tokens)>0:
            prec = precs[tokens[-1]]
            if prec<minprec:
                break
            op=tokens.pop()

            # get the argument on the operator's right
            # this will go to the end, or stop at an operator
            # with precedence <= prec
            arg2 = toTree2(tokens,prec+1)
            node = (op, node, arg2)
        return node

    return toTree2(tokens,0)

print toTree("5+3*4^2+1")

打印:

  

('+',('+','5',('*','3',('^','4','2'))),'1')

在这里试试:

https://ideone.com/RyusvI

请注意,上面的递归下降样式是编写了许多解析器的结果。现在我几乎总是以这种方式解析表达式(递归部分,而不是标记化)。它就像表达式解析器一样简单,它可以很容易地处理括号,以及像赋值运算符一样从右到左关联的运算符。