我正在编写一个称为Calculator(expr)的函数,该函数接受一个中缀表达式,将其转换为后缀表达式(通过调用postfix()),然后在Stack ADT的帮助下评估该表达式。
我必须修改postfix(),以便它可以使用带括号的表达式并返回结果后缀表达式的结果。(当然,只有在括号是平衡的情况下)。
如何在python 3中实现呢?
我真的不知道该怎么办。我在画空白。
def findNextOpr(txt):
"""
>>> findNextOpr(' 3* 4 - 5')
3
>>> findNextOpr('8 4 - 5')
6
>>> findNextOpr('89 4 5')
-1
"""
if not isinstance(txt,str) or len(txt)<=0:
return "error: findNextOpr"
# --- YOU CODE STARTS HERE
operators = '+-*/^'
for i in range(len(txt)):
if txt[i] in operators:
return i
return -1
def isNumber(txt):
"""
>>> isNumber('1 2 3')
False
>>> isNumber('- 156.3')
False
>>> isNumber(' 29.99999999 ')
True
>>> isNumber(' 5.9999x ')
False
"""
if not isinstance(txt, str) or len(txt)==0:
return "error: isNumber"
# --- YOU CODE STARTS HERE
try:
float(txt)
return True
except Exception as other:
return False
def getNextNumber(expr, pos):
"""
>>> getNextNumber('8 + 5 -2',0)
(8.0, '+', 3)
>>> getNextNumber('8 + 5 -2',4)
(5.0, '-', 13)
>>> getNextNumber('4.5 + 3.15 / -5',20)
(-5.0, None, None)
>>> getNextNumber('4.5 + 3.15 / 5',10)
(None, '/', 19)
"""
if not isinstance(expr, str) or not isinstance(
pos, int) or len(expr)==0 or pos<0 or pos>=len(expr):
return None, None, "error: getNextNumber"
# --- YOU CODE STARTS HERE
subexpr = expr[pos:].strip()
if subexpr[0] == '-':
posn = expr.find('-', pos)
oprPos = findNextOpr(expr[posn + 1: ])
if oprPos != -1:
oprPos = oprPos + posn + 1 - pos
else:
oprPos = findNextOpr(expr[pos:])
if oprPos != -1:
oprPos = oprPos + pos
nextOpr = expr[oprPos]
newNumber = expr[pos:oprPos]
else:
nextOpr, oprPos = None, None
newNumber = expr[pos:]
if isNumber(newNumber):
return float(newNumber), nextOpr, oprPos
else :
return None, nextOpr, oprPos
class Node:
def __init__(self, value):
self.value = value
self.next = None
def __str__(self):
return "Node({})".format(self.value)
__repr__ = __str__
class Stack:
'''
>>> x=Stack()
>>> x.pop()
'Stack is empty'
>>> x.push(2)
>>> x.push(4)
>>> x.push(6)
>>> x
Top:Node(6)
Stack:
6
4
2
>>> x.pop()
6
>>> x
Top:Node(4)
Stack:
4
2
>>> len(x)
2
>>> x.peek()
4
'''
def __init__(self):
self.top = None
self.item = 0
def __str__(self):
temp=self.top
out=[]
while temp:
out.append(str(temp.value))
temp=temp.next
out='\n'.join(out)
return ('Top:{}\nStack:\n{}'.format(self.top,out))
__repr__=__str__
def isEmpty(self):
#write your code here
if self.top is None :
return True
else :
return False
def __len__(self):
#write your code here
length = 0
temp = self.top
while temp:
length += 1
temp = temp.next
return length
def peek(self):
#write your code here
if self.top is None:
return "Stack is is empty"
else:
return self.top.value
def push(self,value):
#write your code here
newnode = Node(value)
self.item = value
newnode.next = self.top
self.top = newnode
def pop(self):
#write your code here
if self.top is None:
return "Stack is empty"
else:
element = self.top.value
self.top = self.top.next
return element
parentheses = ['(', ')']
def postfix(expr):
if not balparentheses(expr):
return "error, invalid expression"
number, opr, oprPos = getNextNumber(expr, 0)
if number is None:
return "error, invalid expression"
elif opr is None:
return float(expr)
pos = oprPos + 1
postfix = []
postfixstack = Stack()
postfix = [str(number)]
postfixstack.push(opr)
precedence = {'+' : 1, '-' : 1, '*' : 2, '/' : 2, '^' : 3, '(' : 4, ')' : 4}
while True :
number, opr, oprPos = getNextNumber(expr, pos)
if number is None:
return "error, invalid expression"
if opr is None and number is None:
return postfix
postfix.append(str(number))
if opr is not None:
while not postfixstack.isEmpty():
if precedence[opr] > precedence[postfixstack.peek()]:
break
else:
postfix.append(str(postfixstack.pop()))
postfixstack.push(opr)
else:
while not postfixstack.isEmpty():
postfix.append(str(postfixstack.pop()))
return " ".join(postfix).strip()
pos = oprPos + 1
def balparentheses(txt): #function that checks whether parentheses are balanced
s = Stack()
balanced = True
index = 0
while index < len(txt) and balanced:
symbol = txt[index]
if symbol == '(':
s.push(symbol)
else:
if symbol == ')':
balanced = False
else:
s.pop()
index += 1
if balanced and s.isEmpty():
return True
else:
return False
def compute(opr, num1, num2):
if opr == '+':
return num1 + num2
elif opr == '*':
return num1 * num2
elif opr == '-' :
return num1 - num2
elif opr == '/':
try:
return num1 / num2
except ZeroDivisionError:
return "error, invalid expression"
elif opr == '^':
return num1 ** num2
def calculator(expr):
oplist = ['+', '-', '/', '*', '^']
numbers = [str(float(num)) for num in range(10)]
eval_stack = Stack()
eval_expr = postfix(expr)
alist = eval_expr.split()
for item in alist:
if item in numbers:
eval_stack.push(float(item))
else:
op2 = eval_stack.pop()
op1 = eval_stack.pop()
result = compute(item, op1, op2)
eval_stack.push(result)
return eval_stack.pop()
calculator(' -2 / (-4) * (3 - 2*( 4- 2^3)) + 3')
应该返回8.5。相反,它什么也不返回。 (其余都一样)
calculator('((2))')
应该返回2.0。
calculator('2*(4+2*(5-3^2)+1)+4')
应该返回-2.0
calculator('(-2)*10 - 3*(2 - 3*2)) ')
应该返回“错误,无效的表达式”
calculator('(-2)*10 - 3*/(2 - 3*2) ')
应该返回“错误,无效的表达式”