在 Python 中使用堆栈计算表达式



我想编写一个Python代码,它将使用堆栈计算表达式。我有以下代码,其中numStk是一个包含数字的堆栈和保存运算符的optStk。在表达式 2+3*4-6 中,在循环for末尾,numStack 包含 2126 ;optStk包含-+。现在如何使我的setOps()函数从两个堆栈中弹出元素以执行表达式计算?

def main():
      raw_expression = input("Enter an expression: ")
      expression = raw_expression.replace(" ", "")
      for i in expression:
          if (i in numbers):
              numStk.push(i)
          else:
              setOps(i)
              optStk.push(i)
      ## code needed to evaluate the rest of the elements in stackstack
      return valStk.top()

我的setOps(i)函数如下:

def repeatOps(refOp):
      while (len(valStk) > 1 and operators.index(refOp) <= operators.index(optStk.top())):
      x = numStk.pop()
      y = numStk.pop()
      op = optStk.pop()
      numStk.push(str(eval(x+op+y)))

即使我填写了您遗漏的所有内容,您的代码也存在问题:setOps()似乎被称为repeatOps(); numStk有时被称为valStk;您以错误的顺序进行评估,例如"6-5"被评估为"5-6";你在打电话给eval()

以下是我填写和修改您的代码以解决上述问题:

from collections import OrderedDict
DIGITS = "0123456789"
# position implies (PEMDAS) priority, low to high
OPERATORS = OrderedDict([  
    ['+', lambda a, b: a + b], 
    ['-', lambda a, b: a - b], 
    ['*', lambda a, b: a * b], 
    ['/', lambda a, b: a / b], 
    ])
def operator_priority(character):
    return list(OPERATORS.keys()).index(character)
class Stack(list):
    """ minimalist stack implementation """
    def push(self, thing):
        self.append(thing)
    def top(self):
        return self[-1]
def evaluate(expression):
    numStk = Stack()
    optStk = Stack()
    def setOps(refOp):
        while numStk and optStk and operator_priority(refOp) <= operator_priority(optStk.top()):
            y = numStk.pop()
            x = numStk.pop()
            op = optStk.pop()
            print(x, op, y)  # debugging
            numStk.push(OPERATORS[op](x, y))
    for i in expression:
        if i in DIGITS:
            numStk.push(int(i))
        else:
            setOps(i)
            optStk.push(i)
    if optStk:
        # evaluate the rest of the elements in stacks
        setOps(list(OPERATORS.keys())[0])  # trigger using lowest priority operator
    return numStk.top()
if __name__ == "__main__":
    raw_expression = input("Enter an expression: ")
    expression = raw_expression.replace(" ", "")
    print(evaluate(expression))

远非完美,但可以让你继续前进:

> python3 test.py
Enter an expression: 2+3*4-6
3 * 4
12 - 6
2 + 6
8
>

为了解决您最初的问题,完成评估的关键似乎是在optStk中还剩任何东西时,使用虚构的低优先级运算符运行setOps()

最新更新