【问题标题】:My postfix calculator has multiple errors我的后缀计算器有多个错误
【发布时间】:2014-09-10 04:44:45
【问题描述】:

感谢 StackOverflow 的优秀用户,我终于让我的后缀计算器至少部分工作了。但是,我仍然遇到多个问题。

1.) 我已经用这个代码编辑了一千次:

f = open("expressions.txt")
l = f.readlines()

当我这样做时,我会得到一个 ['5 4 3 * 9 /n', '3 4 - 9 3 * /n'] 的列表。我试图通过并串起列表,我试图事先串起列表,我什至只是假设它已经是一个字符串。之后,我尝试了 split(' ') 和 split ('\n') 和 replace (' ','') 和 replace('/n','') 并且绝对没有任何反应。列表看起来完全一样。

2.) 对于表达式为“int int int int opr opr opr”的表达式,代码有效。但是,在“int int int opr int”的情况下或任何其他两个整数之间存在运算符的情况下,它会计算错误。

3.) 对于上述问题,如果程序读取诸如 3 + 4 之类的中缀表达式,则应该引发异常。那么我如何告诉它 /not/ 接受 3 + 4,除非它已经在已被验证为后缀的表达式,例如 3 + 4 9 8 *。

from ArrayStack import *

numbers = Stack()
operators = Stack()

def main():
    h = 0
    i = 0
    expression = str(input("Enter an expression: "))
    if not expression[0].isdigit():
        raise Exception("ERROR: " + expression + " is an invalid postfix expression.")
    for x in expression:
        if x.isalpha():
            raise Exception("ERROR: " + expression + " is an invalid postfix expression.")   
    if not expression[1].isdigit:
        raise Exception("ERROR: " + expression + " is an invalid postfix expression.")
    expression = expression.split(" ")
    for x in expression:
        if x.isdigit():
            numbers.push(x)
    while h != len(expression):
        if not expression[i-1].isdigit():
            operators.push(expression[i-1])
        i -=1
        h +=1
    print(numbers.data)
    print(operators.data)
    if len(numbers) == 2:
        first = numbers.pop()
        second = numbers.pop()
        check = operators.pop()
        if check == "+":
            temp = int(second) + int(first)
            numbers.push(temp)
        elif check == "-":
            temp = int(second) - int(first)
            numbers.push(temp)
        elif check == "/":
            temp = int(second) / int(first)
            numbers.push(temp)
        elif check == "*":
            temp = int(second) * int(first)
            numbers.push(temp)
        print("Answer:", numbers.data[0])
    while len(numbers) > 2:
        first = numbers.pop()
        second = numbers.pop()
        check = operators.pop()
        if check == "+":
            temp = int(second) + int(first)
            numbers.push(temp)
        elif check == "-":
            temp = int(second) - int(first)
            numbers.push(temp)
        elif check == "/":
            temp = int(first) / int(second)
            numbers.push(temp)
        elif check == "*":
            temp = int(second) * int(first)
            numbers.push(temp)
        if len(numbers) == 2:
            answer = numbers.pop()
            finalNum = numbers.pop()
            finalOpr = operators.pop()
            if finalOpr == "+":
                temp = int(answer) + int(finalNum)
                numbers.push(temp)
            elif finalOpr == "-":
                temp = int(finalNum) - int(answer)
                numbers.push(temp)
            elif finalOpr == "/":
                temp = int(finalNum) / int(answer)
                numbers.push(temp)
            elif finalOpr == "*":
                temp = int(answer) * int(finalNum)
                numbers.push(temp)
            print("Answer:", numbers.data[0])
            break

main()

【问题讨论】:

  • l = [x.strip().split() for x in f] 会做你需要的。
  • 你的函数太长了,试着把每个函数限制在 24 行左右,或者至少一屏。将您的代码拆分为不同的函数将使您能够逐个调试、验证和注释它们,将错误跟踪到有限的行集。

标签: python stack postfix-notation


【解决方案1】:

1) @PadraicCunningham 在对该问题的评论中已回答:

lines = [line.strip().split() for line in source_file]

2) 您不能以这种方式将数字和运算符分成两个单独的堆栈。操作员必须在看到操作员时对堆栈顶部的两个元素进行操作。实现这一点的最简单方法是省略运算符堆栈并立即使用当前编号堆栈评估运算符。

3) 3 + 4 9 8 * 不是有效的后修复表达式。有一个3,然后是一个+,它只有一个参数,而不是它需要的两个参数。通过在每次处理运算符时和评估整个表达式后查看堆栈,可以轻松识别无效表达式。在每个运算符之前,堆栈上必须至少有足够的操作数用于该运算符。在计算表达式后,应该只有一个值,即结果,留在堆栈中。

因此归结为:只需评估后缀表达式并在途中遇到问题时引发异常。


更新:评估后缀符号的简单函数:

from operator import add, sub, mul, div


OPERATOR2FUNC = {'+': add, '-': sub, '*': mul, '/': div}


def evaluate_postfix(tokens):
    operands = list()
    for token in tokens:
        if token.isdigit():
            operands.append(int(token))
        else:
            try:
                operation = OPERATOR2FUNC[token]
            except KeyError:
                raise Exception('unknown operation {0!r}'.format(token))
            try:
                operand_b = operands.pop()
                operand_a = operands.pop()
            except IndexError:
                raise Exception(
                    'not enough operands on stack ({0}) for {1!r}'.format(
                        operands, token
                    )
                )
            operands.append(operation(operand_a, operand_b))

    if len(operands) != 1:
        raise Exception('still excess operands on stack: {0}'.format(operands))

    return operands.pop()

【讨论】:

    猜你喜欢
    • 2017-01-27
    • 1970-01-01
    • 2015-07-17
    • 1970-01-01
    • 1970-01-01
    • 2022-11-30
    • 2012-08-29
    • 2021-08-20
    • 2018-03-20
    相关资源
    最近更新 更多