繁体   English   中英

在python中评估postfix?

[英]Evaluating postfix in python?

我想编写一个功能来评估作为列表传递的后缀表达式。 到目前为止,我已经:

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()

但是我认为我的方法是错误的。 救命?

您有一些问题:

  1. 遇到运算符后,您将丢弃该值。 要解决此问题,您必须将任何运算符的结果推回堆栈,然后继续进行下一步。
  2. 遇到数字时,您不会跳过其余的逻辑(这不会使您的代码返回错误的答案,但仍然不是很聪明)
  3. 您的函数不返回任何内容。

这样的事情应该起作用:

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:您可以直接尝试将symbol (以string开头)转换为int ,而不是检查symbol是否在0到9之间。 如果成功,则可以将symbol视为操作数。 (这使您的代码可以处理多位数的数字。)

更改#2:如果text出现非数字非运算符,则会引发错误。 (您不希望其他任何内容。)

变更#3:使用eval而不是写出每个运算符。 eval有很多安全方面的问题,但是我想在这里,因为我们确保所有内容都是数字或运算符,所以可以。

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

变更#5:清单用尽后返回s.pop() 您可能要添加一行以确认s此处仅包含一个值。

注意:请注意,此代码假定s每次遇到运算符时都将包含两个值。 你可能想赶上,如果这是不是真的有另外一个将要引发的错误try / except对语句。

def evalPostfix(text):
    s = Stack()
    for symbol in text:
        try:
            result = int(symbol)
        except ValueError:
            if symbol not in '+-*/':
                raise ValueError('text must contain only numbers and operators')
            result = eval('%d %s %d' % (s.pop(), symbol, s.pop()))
        s.push(result)
    return s.pop() 

Hosane为您的问题提供了很好的详细答案,但我认为我看到了一个错误,尽管我承认我不是该主题的专家。

由于您使用的是流行音乐,因此您的计算将如下所示。 (堆栈中的最后一个数字)(运算符)(堆栈中的倒数第二个数字),例如,如果您的列表中有[“ 3”,“ 2”,“ +”],则得到3 + 2

这对于加法或乘法很好,但是如果您进行除法或减法运算,则会导致错误的答案。 例如,后修复中的(3-2)将为[3,2,-]。 您的代码应该将其计算为(3-2)时将其计算为(2-3)。

因此,如果需要,您应该更改除法和减法;

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

工作代码是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()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM