需求
- 实现加减乘除及扩号优先级解析
-
用户输入 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 #! /usr/bin/env python3 2 # -*- coding:utf-8 -*- 3 # Author:Jailly 4 5 import re 6 7 # 匹配单次加减运算表达式的re编译对象 8 sub_pm = re.compile(r''' 9 \s* 10 (?P<operand1>((-?[1-9]\d*)|0)(\.\d+)?) # 第一个操作数 11 \s* 12 (?P<operator>[+-]) # 操作符 13 \s* 14 (?P<operand2>((-?[1-9]\d*)|0)(\.\d+)?) # 第二个操作数 15 ''', re.X) 16 17 # 匹配单次乘除运算表达式的re编译对象 18 sub_md = re.compile(''' 19 \s* 20 (?P<operand1>((-?[1-9]\d*)|0)(\.\d+)?) # 第一个操作数 21 \s* 22 (?P<operator>[*/]) # 操作符 23 \s* 24 (?P<operand2>((-?[1-9]\d*)|0)(\.\d+)?) # 第二个操作数 25 ''',re.X) 26 27 28 def pm(exp): 29 ''' 30 最底层的加减,无乘除,无括号 31 :param exp:只含有加减的运算式字符串 32 :param sub_pm:匹配单次加减运算表达式的re编译对象 33 :return:递归返回将逐次运算结果代入原式后的表达式 34 ''' 35 36 sub_exp = sub_pm.search(exp) 37 38 if sub_exp: 39 operand1 = float(sub_exp.group('operand1')) 40 operand2 = float(sub_exp.group('operand2')) 41 res = ( operand1 + operand2 ) if sub_exp.group('operator') == '+' else ( operand1 - operand2 ) 42 43 # 从左到右计算,只取匹配到的第一个替换,count = 1 44 new_exp = sub_pm.sub(str(res),exp,count=1) 45 46 return pm(new_exp) 47 48 else: 49 return exp 50 51 52 def md(exp): 53 ''' 54 最底层的乘除,可有加减,但无括号 55 :param exp:只含有乘除的运算式字符串 56 :return:递归返回将逐次运算结果代入原式后的表达式 57 ''' 58 sub_exp = sub_md.search(exp) 59 60 if sub_exp: 61 operand1 = float(sub_exp.group('operand1')) 62 operand2 = float(sub_exp.group('operand2')) 63 res = ( operand1 * operand2 ) if sub_exp.group('operator') == '*' else ( operand1 / operand2 ) 64 65 # 从左到右计算,只取匹配到的第一个替换,count = 1 66 new_exp = sub_md.sub(str(res),exp,count=1) 67 68 return md(new_exp) 69 else: 70 return exp 71 72 73 def brackets(exp): 74 ''' 75 供brackets2调用,计算括号内的运算式 76 :param exp:只含有单层括号的运算式字符串 77 :return:运算结果的字符串形式 78 ''' 79 80 exp1 = md(exp) 81 exp2 = pm(exp1) 82 83 res = re.search(r'\((?P<res>.+)\)',exp2).group('res') 84 85 return res 86 87 def brackets2(exp): 88 ''' 89 多层括号运算 90 :param exp:含有多层括号的运算式字符串 91 :return: 92 ''' 93 min_bra_c = re.compile(r'\([^()]+\)') 94 min_bra_m = min_bra_c.search(exp) 95 96 if min_bra_m: 97 min_bra_exp = min_bra_m.group() 98 res = brackets(min_bra_exp) 99 new_exp = min_bra_c.sub(res,exp,count=1) 100 101 return brackets2(new_exp) 102 else: 103 return exp 104 106 107 def calc(exp): 108 '''主程序''' 109 110 exp1 = brackets2(exp) 111 exp2 = md(exp1) 112 exp3 = pm(exp2) 113 114 return float(exp3) 115 116 117 if __name__ == '__main__': 118 119 while 1: 120 q = input('请输入您的运算式:') 121 if q == 'q': 122 exit() 123 else: 124 try: 125 print('结果为:\033[1;31m %s \033[0m'%str(calc(q))) 126 except: 127 print('\033[1;31m请输入正确的运算式!\033[0m')