我的后缀计算器有多个错误

0 投票
1 回答
653 浏览
提问于 2025-04-18 13:55

感谢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.) 对于像“整数 整数 整数 整数 操作符 操作符 操作符”这样的表达式,代码是可以正常工作的。但是如果是“整数 整数 整数 操作符 整数”或者任何有操作符夹在两个整数之间的情况,它就会算错。

3.) 针对上面的问题,程序应该在读取像3 + 4这样的中缀表达式时抛出异常。那么我该怎么做才能让它不接受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()

1 个回答

0

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

撰写回答