在python中评估postfix?

时间:2015-05-06 03:52:03

标签: python postfix-notation

我想编写一个函数来评估作为列表传递的后缀表达式。到目前为止我有:

def evalPostfix(text):
    s = Stack()
    for symbol in text:
        if symbol in "0123456789":
            s.push(int(symbol))
        if not s.is_empty():
            if symbol == "+":
                plus = s.pop() + s.pop()
            if symbol == "-":
                plus = s.pop() - s.pop()
            if symbol == "*":
                plus = s.pop() * s.pop()
            if symbol == "/":
                plus = s.pop() / s.pop()

但我认为我采取了错误的做法。帮助

4 个答案:

答案 0 :(得分:4)

你有一些问题:

  1. 您遇到操作员后丢弃该值。要解决此问题,您必须将任何操作员的结果推回堆栈,然后继续执行下一步。
  2. 当遇到一个数字时,你不会跳过其余的逻辑(它不会让你的代码返回错误的答案,但仍然不是很聪明)。
  3. 您的功能不会返回任何内容。
  4. 这样的事情应该有效:

    def eval_postfix(text):
        s = list()
        for symbol in text:
            if symbol in "0123456789":
                s.append(int(symbol))
    
            plus = None
            elif not s.is_empty():
                if symbol == "+":
                    plus = s.pop() + s.pop()
                elif symbol == "-":
                    plus = s.pop() - s.pop()
                elif symbol == "*":
                    plus = s.pop() * s.pop()
                elif symbol == "/":
                    plus = s.pop() / s.pop()
            if plus is not None:
                s.append(plus)
            else:
                 raise Exception("unknown value %s"%symbol)
        return s.pop()
    

答案 1 :(得分:1)

这是一个可能适合您的解决方案。我试图尽可能少地更改你的代码。

更改#1:您可能只是尝试将symbol(以symbol开头)转换为{{1},而不是检查string是否在0到9之间。 }。如果成功,您可以将int视为操作数。 (这允许您的代码处理多位数字。)

更改#2:如果symbol中出现非数字非操作符,则引发错误。 (你不希望其他任何东西在那里。)

更改#3:使用text而不是写出每个运算符。 eval带来了许多安全问题,但我想在这里,因为我们确保所有内容都是数字或操作符,所以我们没问题。

更改#4:将中间结果推入堆栈。

更改#5:在列表用尽后返回eval。您可能需要添加一行来确认s.pop()此时只包含一个值。

警告:请注意,此代码假定每次遇到运算符时s将包含两个值。如果对于另一对s / try对语句不适用,您可能希望捕获可能引发的错误。

except

答案 2 :(得分:1)

Hosane已经为您的问题提供了非常详细的答案,但我认为我发现了一个错误,尽管我承认我不是这方面的专家。

由于你使用pop,你的计算就是这样的。 (堆栈中的最后一个数字)(运算符)(堆栈中的倒数第二个) 例如,如果您的列表中有[" 3"," 2"," +"],则会得到3 + 2

这适用于加法或乘法,但如果你采用除法或减法,这将导致错误的答案。例如(3-2)在后期修复中将是[3,2, - ]。你的代码会将它计算为(2-3)它应该是(3-2)。

所以你应该改变除法和减法,如果情况是;

elif symbol=="-":
        s.append(-stack.pop() + stack.pop())
elif symbol=="/":
        s.append(1/stack.pop() * stack.pop())

答案 3 :(得分:0)

工作代码,是K&R C示例的翻译版本,

def eval_postfix(text):

    stack = []
    tokens = text.split(" ")

    for token in tokens:

        if token.strip() == '':
            continue 

        elif token == "+":
            stack.append(stack.pop() + stack.pop())

        elif token == "-":
            op2 = stack.pop() 
            stack.append(stack.pop() - op2)

        elif token == '*':
            stack.append(stack.pop() * stack.pop())

        elif token == '/':
            op2 = stack.pop()
            if op2 != 0.0:
                stack.append(stack.pop() / op2)
            else:
                raise ValueError("division by zero found!")

        elif (is_number(token)):
                stack.append(float(token))

        else:
            raise ValueError("unknown token {0}".format(token))


    return stack.pop()