我的后缀计算器有多个错误
感谢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 个回答
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()