在Python中使用堆栈评估表达式

时间:2017-10-16 01:14:30

标签: python-3.x

我想写一个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)))

1 个答案:

答案 0 :(得分:0)

即使我填写了您遗漏的所有内容,您的代码也会出现问题: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
>

要解决原始问题,如果setOps()中还有任何内容,那么完成评估的关键似乎是使用虚构的低优先级运算符运行optStk