如何以前缀表示法返回修改后的输入

时间:2016-01-05 18:43:18

标签: python

我正在尝试制作一个执行数学的程序 作为输入,我得到了一个前缀表示法,例如['+',['-',['multiply',3,5],8],2]

我执行最内部操作后的问题,如何修改原始输入?例如,这里我对我的代码的期望是它将35,(=15)子结果8相乘,最后添加{{1}对它。为此,我首先计算2。在我必须使用输入['multiply',3,5]运行函数之后。然而几个小时过去了,我找不到办法。

['+',['-',15,8],2]

2 个答案:

答案 0 :(得分:2)

有一个非常简单的评估策略。首先,请注意前缀表示法定义

      +
     / \
    -   2
   / \
  *   8
 / \
3   5

因此,构建该树并以递归方式评估它是很有吸引力的:

def evaluate(root):
    if root == '+':
        return evaluate(left) + evaluate(right)
    elif root == '-':
        return evaluate(left) - evaluate(right)
    elif root == '*':
        return evaluate(left) * evaluate(right)
    elif root == '/':
        return evaluate(left) / evaluate(right)
    else:
        return root

但您不必构建树:

def evaluate(seq):
    if type(seq) == list:
        op, left, right = seq[0], seq[1], seq[2]

        if op == '+':
            return evaluate(left) + evaluate(right)
        elif op == '-':
            return evaluate(left) - evaluate(right)
        elif op == '*':
            return evaluate(left) * evaluate(right)
        elif op == '/':
            return evaluate(left) / evaluate(right)
    else:
        return seq

答案 1 :(得分:1)

您可以通过检查是否还有其他列表来使用递归函数。如果没有,则进行数学运算,并用答案替换刚刚计算的列表的位置

import operator
def kenobi(l):
    if isinstance(l[1],list):
        l[1] = kenobi(l[1])
    return do_math(l)

def do_math(l):
    #print l
    ops = {'+': operator.add, '-': operator.sub, '*': operator.mul, '/': operator.div}
    return ops[l[0]](l[1],l[2])

print kenobi(['+',['-',['*',3,5],8],2])

9

或者,如果您要在索引1处拥有不在列表中的列表,则可以将其更改为

import operator

def kenobi(l):
    ops = {'+': operator.add, '-': operator.sub, '*': operator.mul, '/': operator.div}

    for i in xrange(1,len(l)):
        if isinstance(l[i],list):
            l[i] = kenobi(l[i])

    return ops[l[0]](l[1],l[2])

print kenobi(['+',['-',['*',['*',5,5],['+',3,5]],8],2])

194