作业 2, 模拟计算器开发:
实现加减乘除及拓号优先级解析
用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),运算后得出结果,结果必须与真实的计算器所得出的结果一致 2776672.6952380957
流程图:
详细代码:
1 #!usr/bin/env python 2 #-*-coding:utf-8-*- 3 # Author calmyan 4 import re 5 #b='1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )' 6 #b='1 - 2 * ( (60-30 +(-40/5) * (9-2**5//3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)// (16-3*2) )' 7 #print(b) 8 9 def list_format(b):#格式化字符串函数 10 b=re.sub(' ','',b) 11 b=[i for i in re.split('(\-?\d+\.*\d*)',b) if i]#循环判断,i 不为空,添加到列表 去空字符 -开头加后面的数字 12 #print(b) 13 tmp_list=[]#定义一个临时列表 14 while True: 15 if len(b)==0:break#如果列表为空就退出 16 emp=b.pop(0)#取出第一个元素 17 if (len(tmp_list)==0 and re.search('^\-\d*$',emp)) or (len(tmp_list)>0 and re.search('[\+\-\*\/\(\)]$',tmp_list[-1]) ):#判断开头与中间的负数 18 tmp_list.append(emp) 19 continue 20 sny_nl=[i for i in re.split('([\+\-\*\/\(\)])',emp) if i]#对运算符进行分割 21 22 for index, i in enumerate(sny_nl): 23 if i==' ':#去空格判断 24 sny_nl.pop(index)#删除空格项 25 tmp_list+=sny_nl 26 27 return tmp_list#返回列表 28 29 def Prioty(str_n,i):#比较优先级函数 30 lev1=['+','-'] 31 lev2=['*','/'] 32 lev3=['('] 33 lev4=[')'] 34 if str_n in lev1: 35 if i in lev2 or i in lev3:#如果str_n 为+ - i 在2,3级时返回小于 36 return 1 37 else: 38 return 3 39 elif str_n in lev2:#如果str_n 为*/ i 在3级时返回小于 40 if i in lev3: 41 return 1 42 else: 43 return 3 44 elif str_n in lev3:#如果str_n 为(i 在4级时返回等于 45 if i in lev4: 46 return 2 47 else: 48 return 1 49 50 def sny(str):#判断是否为运算符 51 sny_l=['+','-','*','/','**','//','(',')'] 52 tag=False 53 if str in sny_l: 54 return True#是运算符返回真 55 else: 56 return tag 57 58 def opera(num1,operation,num2):#运算函数 59 res=0 60 if operation=='+': 61 res=num1+num2 62 if operation=='-': 63 res=num1-num2 64 if operation=='*': 65 res=num1*num2 66 if operation=='/': 67 res=num1/num2 68 return res 69 70 def main(c):#主函数 71 numbe_list=[]#定义数字堆栈 72 sny_list=[]#定义运算符堆栈 73 for i in c: 74 if sny(i):#不是运算运 75 while True: 76 #print(numbe_list) 77 #print(sny_list) 78 if len(sny_list)==0:#如果列表为空,即第一个就无条件加入 79 sny_list.append(i) 80 break 81 prty=Prioty(sny_list[-1],i)# 82 if prty==1:#如果为一级 83 sny_list.append(i)#运算符继续添加 84 break 85 elif prty==2:#如果为二级 86 sny_list.pop()#运算符要取出最后一个 87 break 88 elif prty==3:#如果为三级 89 operation=sny_list.pop()#运算符==取出最后一个 90 num2=numbe_list.pop()#取出数字二 91 num1=numbe_list.pop()#取出数字一 92 numbe_list.append(opera(num1,operation,num2))#数字列表添加运算的结果 93 #print(numbe_list,sny_list) 94 continue 95 else: 96 i = float(i)#转为浮点数 97 numbe_list.append(i)#添加到数字列表 98 else: 99 operation=sny_list.pop()#运算符==取出最后一个 100 num2=numbe_list.pop()#取出数字二 101 num1=numbe_list.pop()#取出数字一 102 numbe_list.append(opera(num1,operation,num2))#数字列表添加运算的结果 103 #print(numbe_list,sny_list) 104 if len(sny_list):#如果运算符列表不为空再做一个运算 105 operation=sny_list.pop()#运算符==取出最后一个 106 num2=numbe_list.pop()#取出数字二 107 num1=numbe_list.pop()#取出数字一 108 numbe_list.append(opera(num1,operation,num2))#数字列表添加运算的结果 109 return numbe_list[0] 110 111 #程序开始 112 print("\033[35;1m欢迎使用python简易计算器\033[0m".center(60,'=')) 113 if __name__ =='__main__': 114 while True: 115 b=input('请输入你要计算的内容,按\033[31;1mQ/q\033[0m退出:') 116 if b=='q' or b=='Q': 117 exit() 118 #print(c) 119 try: 120 c=list_format(b)#运行输入函数格式化字符串,存入列表 121 number=main(c) 122 print(number) 123 except Exception as e:#出错可返回操作 124 print('输入有误,请重新输入')
来源:https://www.cnblogs.com/uge3/p/6900468.html