python基础篇14-计算器练习

要求:

# 实现加减乘除及拓号优先级解析
# 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )
# 等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),运算后得出结果,
# 结果必须与真实的计算器所得出的结果一致

 

  1 #__author: lriwu
  2 #date 2018/1/30
  3 
  4 # 实现加减乘除及拓号优先级解析
  5 # 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )
  6 # 等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),运算后得出结果,
  7 # 结果必须与真实的计算器所得出的结果一致
  8 
  9 import re
 10 
 11 def check_expression(string):
 12     ckeck_result = True
 13     #检查括号是否匹配
 14     if not string.count('(') == string.count(')'):
 15         print("表达式错误,括号未闭合")
 16         ckeck_result = False
 17     if re.findall('[a-z]+',string.lower()):
 18         print("表达式错误,含非法字符")
 19         ckeck_result = False
 20 
 21     return ckeck_result
 22 
 23 
 24 def format_string(string):
 25     string = string.replace(' ','')
 26     string = string.replace('+-','-')
 27     string = string.replace('-+', '-')
 28     string = string.replace('++', '+')
 29     string = string.replace('--', '+')
 30     string = string.replace('*+', '*')
 31     string = string.replace('/+', '/')
 32     return string
 33 
 34 def calc_mul_div(string):
 35     # 从字符串中获取乘除表达式  (-3.1*-2.1+1-2*3)
 36     regular = '\d+\.?\d*([*/]|\*\*)[\-]?\d+\.?\d*'
 37     #如果还能找到乘或除表达式
 38     while re.findall(regular,string):
 39         #获取表达式
 40         expression = re.search(regular,string).group()
 41 
 42         #如果时乘法
 43         if expression.count('*') == 1:
 44             #获取要计算的两个数
 45             x,y = expression.split('*')
 46             #计算结果
 47             mul_result = str(float(x) * float(y))
 48             #将计算的表达式替换为计算的结果值
 49             string = string.replace(expression,mul_result)
 50             string = format_string(string)
 51 
 52         # 如果时除法
 53         if '/' in expression:
 54             # 获取要计算的两个数
 55             x, y = expression.split('/')
 56             # 计算结果
 57             mul_result = str(float(x) / float(y))
 58             # 将计算的表达式替换为计算的结果值
 59             string = string.replace(expression, mul_result)
 60             string = format_string(string)
 61 
 62     return string
 63 
 64 
 65 def calc_add_sub(string):  #(-2.1+2.1-1+2)
 66     #定义正则表达式
 67     add_regular = '\-?\d+\.?\d*\+\-?\d+\.?\d*'
 68     sub_regular = '\-?\d+\.?\d*\-\-?\d+\.?\d*'
 69     # 从字符串中获取加减表达式
 70     # 计算加法
 71     while re.findall(add_regular, string):
 72         # 获取表达式
 73         add_list = re.findall(add_regular, string)
 74         for add_str in add_list:
 75             #获取两个加法的数
 76             x,y = add_str.split('+')
 77             add_result = '+'+str(float(x) + float(y))
 78             string = string.replace(add_str,add_result)
 79         string = format_string(string)
 80 
 81     #计算减法
 82     while re.findall(sub_regular, string):
 83         # 获取表达式
 84         sub_list = re.findall(sub_regular, string)
 85         for sub_str in sub_list:
 86             #获取两个减法的数
 87             members = sub_str.split('-')
 88             if len(members) == 3:
 89                 sub_result = 0
 90                 for v in members:
 91                     sub_result -= float(sub_result)  #sub_result = sub_result -float(sub_result)
 92 
 93             else:
 94                 x,y = members
 95                 sub_result = float(x) - float(y)
 96 
 97             string = string.replace(sub_str, "+"+str(sub_result))
 98         string = format_string(string)
 99     return string
100 
101 
102 
103 
104 
105 
106 
107 
108 
109 
110 
111 
112 
113 
114 
115 
116 if __name__ == '__main__':
117     source = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
118     if check_expression(source):
119         print("source:",source)
120         print("eval result:",eval(source))
121         source = format_string(source)
122         print(source)
123 
124         while source.count('(') > 0:
125             strs = re.search('\([^()]+\)',source).group() #['(-40/5)', '(9-2*5/3+7/3*99/4*2998+10*568/14)', '(-4*3)', '(16-3*2)']
126             #将括号的表达式进行乘除运算
127             replace_str = calc_mul_div(strs)
128 
129             #将括号的表达式进行加减运算
130             replace_str = calc_add_sub(replace_str)
131 
132             #将括号的字符串替换为计算结果,结果包含括号(),替换时去掉括号():[1:-1]
133             source = format_string(source.replace(strs,replace_str[1:-1]))
134         #没有括号就到最后单一表达式了
135         else:
136             #算乘除
137             replace_str = calc_mul_div(source)
138             #算加减
139             replace_str = calc_add_sub(replace_str)
140             source = source.replace(source,replace_str)
141             #source = source.replace(source, replace_str))
142 
143         print(source)

 

posted @ 2018-02-01 15:00  lriwu  阅读(235)  评论(0编辑  收藏  举报