import math
# merge
def merge(arg):
# merge the deciaml
while (True):
try:
x=arg.index('.')
except:
break
arg[x-1]+=arg[x]
arg[x-1]+=arg[x+1]
del arg[x]
del arg[x]
# combined trigonometric function
while True:
try:x=arg.index('i')
except:
break
arg[x-1]+=arg[x]
arg[x-1]+=arg[x+1]
del arg[x]
del arg[x]
while True:
try:x=arg.index('o')
except:
break
arg[x-1]+=arg[x]
arg[x-1]+=arg[x+1]
del arg[x]
del arg[x]
while True:
try:x=arg.index('a')
except:
break
arg[x-1]+=arg[x]
arg[x-1]+=arg[x+1]
del arg[x]
del arg[x]
while True:
try:x=arg.index('q')
except:
break
arg[x-1]+=arg[x]
arg[x-1]+=arg[x+1]
arg[x-1]+=arg[x+2]
del arg[x]
del arg[x]
del arg[x]
# combined multidigit
y=len(arg)
i=1
while (i<y):
if arg[i-1]=='(' or arg[i-1]==')' or arg[i-1]=='+' or arg[i-1]=='-' or arg[i-1]=='*' or arg[i-1]=='/' or arg[i-1]=='^' or arg[i-1]=='sin' or arg[i-1]=='cos' or arg[i-1]=='tan' or arg[i-1]=='sqrt':
i+=1
continue
if arg[i]!='(' and arg[i]!=')' and arg[i]!='+' and arg[i]!='-' and arg[i]!='*' and arg[i]!='/' and arg[i]!='^' and arg[i]!='sin' and arg[i]!='cos' and arg[i]!='tan' and arg[i]!='sqrt':
arg[i-1]+=arg[i]
del arg[i]
y-=1
i-=1
i+=1
return arg
#get the list of Reverse Polish Notation
def get_RPN(arg):
Pri={'(':0,')':0,'+':1,'-':1,'*':2,'/':2,'^':3}
#add symbol to Stack1
#add the list of Reverse Polish Notation to Stack2
Stack1=[]
Stack2=[]
for z in arg:
if z=='sin' or z=='cos' or z=='tan' or z=='sqrt':
Stack1.append(z)
elif z=='(':
Stack1.append(z)
elif z==')':
top=Stack1.pop()
while(top!='('):
Stack2.append(top)
top=Stack1.pop()
if Stack1[-1]=='sin' or Stack1[-1]=='cos' or Stack1[-1]=='tan' or Stack1[-1]=='sqrt':
Stack2.append(Stack1.pop())
elif z=='+' or z=='-' or z=='*' or z=='/' or z=='^':
if len(Stack1)==0:
Stack1.append(z)
else:
top1=Stack1[-1]
if Pri[z]>Pri[top1]:
Stack1.append(z)
else:
while(1):
if Pri[z]>Pri[top1]:
break
Stack2.append(top1)
Stack1.pop()
if len(Stack1)==0:
break
top1=Stack1[-1]
Stack1.append(z)
else:
Stack2.append(z)
while(len(Stack1)!=0):
Stack2.append(Stack1.pop())
RPN=Stack2
return RPN
#Calculate the value of the Reverse Polish Notation
def process_RPN(RPN):
if len(RPN)==0:
return 0
if len(RPN)==1:
return RPN[0]
p=len(RPN)
w=0
while w<p:
if RPN[w]=='+':
RPN[w-2]=float(RPN[w-2])
RPN[w-1]=float(RPN[w-1])
RPN[w-2]+=RPN[w-1]
del RPN[w-1]
del RPN[w-1]
w-=2
p-=2
elif RPN[w]=='-':
RPN[w-2]=float(RPN[w-2])
RPN[w-1]=float(RPN[w-1])
RPN[w-2]-=RPN[w-1]
del RPN[w-1]
del RPN[w-1]
w-=2
p-=2
elif RPN[w]=='*':
RPN[w-2]=float(RPN[w-2])
RPN[w-1]=float(RPN[w-1])
RPN[w-2]*=RPN[w-1]
del RPN[w-1]
del RPN[w-1]
w-=2
p-=2
elif RPN[w]=='/':
RPN[w-2]=float(RPN[w-2])
RPN[w-1]=float(RPN[w-1])
try:
a=RPN[w-2]/RPN[w-1]
except ZeroDivisionError:
print('Zero Division Error')
break
finally:
RPN[w-2]=a
del RPN[w-1]
del RPN[w-1]
w-=2
p-=2
elif RPN[w]=='^':
RPN[w-2]=float(RPN[w-2])
try:
RPN[w-1]=int(RPN[w-1])
except ValueError:
print('Value Error')
break
finally:
RPN[w-2]**=RPN[w-1]
del RPN[w-1]
del RPN[w-1]
w-=2
p-=2
elif RPN[w]=='sin':
RPN[w-1]=float(RPN[w-1])
RPN[w-1]=math.sin(RPN[w-1])
del RPN[w]
w-=1
p-=1
elif RPN[w]=='cos':
RPN[w-1]=float(RPN[w-1])
RPN[w-1]=math.cos(RPN[w-1])
del RPN[w]
w-=1
p-=1
elif RPN[w]=='tan':
RPN[w-1]=float(RPN[w-1])
try:
RPN[w-1]=math.tan(RPN[w-1])
except ZeroDivisionError:
print('Zero Division Error')
finally:
del RPN[w]
w-=1
p-=1
elif RPN[w]=='sqrt':
RPN[w-1]=float(RPN[w-1])
try:
RPN[w-1]=math.sqrt(RPN[w-1])
except:
print('Negative Numbers are not allowed')
finally:
del RPN[w]
w-=1
p-=1
w+=1
if p==1:
return RPN[0]
def main():
while True:
arg=list(str(input()))
print('Reverse Polish Notation: ', get_RPN(merge(arg)), '\n')
print('Result: ', process_RPN(get_RPN(merge(arg))))
if __name__ == '__main__':
main()
基于Python语言的逆波兰式简易计算器
最新推荐文章于 2023-04-21 19:00:00 发布