简体   繁体   English

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

[英]My postfix calculator has multiple errors

Thanks to the wonderful users of StackOverflow, I have finally got my postfix calculator at least partially working. 多亏了StackOverflow的出色用户,我终于使我的后缀计算器至少可以部分工作了。 However, I am still running into multiple issues. 但是,我仍然遇到多个问题。

1.) I have edited the code a thousand times with this: 1.)我已经用此代码编辑了上千次:

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

When I do this, I get a list of ['5 4 3 * 9 /n', ' 3 4 - 9 3 * /n']. 当我这样做时,我得到一个['5 4 3 * 9 / n','3 4-9 3 * / n']的列表。 I have tried to go through and string the list, I have tried to string the list beforehand, and I have even just assumed it was already a string. 我试图遍历该列表,并事先尝试对该列表进行字符串化,甚至我只是假设它已经是一个字符串。 After that, I tried both split(' ') and split ('\\n') and replace (' ','') and replace('/n','') and absolutely nothing happens. 之后,我尝试了split('')和split('\\ n')以及replace('','')和replace('/ n',''),但绝对没有任何反应。 The list looks exactly the same. 该列表看起来完全一样。

2.) For expressions in which the expression is "int int int int opr opr opr", the code works. 2.)对于表达式为“ int int int int opr opr opr opr”的表达式,该代码有效。 However, in the case of "int int int opr int" or any other time where there is an operator between two integers, it miscalculates. 但是,在“ int int int opr int”或任何其他两个整数之间存在运算符的情况下,它会计算错误。

3.) And with the above problem, the program is supposed to raise an exception if it reads an infix expression such as 3 + 4. So how can I tell it /not/ to accept 3 + 4 unless it's already in an expression that's been verified as postfix such as 3 + 4 9 8 *. 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()

1) Was already answered by @PadraicCunningham in a comment to the question: 1)@PadraicCunningham已经在对问题的评论中回答了:

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

2) You can't separate the number and the operators into two separate stacks that way. 2)您不能以这种方式将数字和运算符分成两个单独的堆栈。 An operator must operate on the two elements on the top of the stack at the time the operator is seen. 在看到操作员时,操作员必须对堆栈顶部的两个元素进行操作。 The easiest way to achieve that is to leave out the operator stack and evaluate an operator immediately with the current number stack. 最简单的方法是忽略运算符堆栈,并立即使用当前数字堆栈评估运算符。

3) 3 + 4 9 8 * isn't a valid post fix expression. 3) 3 + 4 9 8 *不是有效的后缀表达式。 There is a 3 and then a + that just has one argument instead of the two it needs. 有一个3和一个+ ,只有一个参数而不是它需要的两个参数。 Recognizing invalid expressions can be easily done by looking at the stack each time an operator is processed and after the whole expression is evaluated. 每次处理运算符时以及在评估整个表达式之后,都可以通过查看堆栈来轻松地识别无效表达式。 Before each operator there have to be at least enough operands on the stack for that operator. 在每个操作符之前,堆栈上至少必须有足够的操作数用于该操作符。 After the expression is evaluated there should only be one value, the result, left on the stack. 在对表达式求值后,结果应仅剩一个值,即结果,留在堆栈上。

So it boils down to: Just evaluate the postfix expression and raise an Exception if you encounter a problem on the way. 因此,可以归结为:仅计算后缀表达式,如果在途中遇到问题,则引发Exception。


Update: A simple function to evaluate postfix notation: 更新:一个简单的函数来评估后缀表示法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM