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

时间:2014-07-18 23:42:06

标签: python stack postfix-notation

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

1。)我用这个编辑了代码一千次:

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

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

2。)对于表达式为“int int int int opr opr opr”的表达式,代码可以正常工作。但是,在“int int int opr int”的情况下或者在两个整数之间存在运算符的任何其他时间,它会计算错误。

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 :(得分: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()