作业 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
