简单版计算器

解题思路

    一、计算器运算规则

            优先级                    匹配格式

    1. 小括号(最底层的)                    括号里没有括号

           小括号里算式计算优先级:

                     2.幂运算            (正数)**(正数)、(正数)**(负数)     ---支持小数

                     3.乘除                (正数或负数)(*/)(正数或负数)         ---支持小数

                     4.加减                (正数或负数)(+-)(正数或负数)         ---支持小数

    二、运算流程

    1.search匹配第一个最底层的括号

    2.通过match对象的groups方法获取括号里算式

    3.对括号内的算式进行幂运算匹配

    4.调用幂运算函数对匹配到的对象进行处理

    5.用sub将结果替换括号内算式的匹配到的对象

    6.重复3、4、5,直到没有匹配对象

    7.对替换的算式进行乘除运算匹配

    8.调用乘除运算函数对匹配到的对象进行处理

    9.用sub将结果替换括号内算式的匹配到的对象

    10.重复7、8、9直到没有匹配对象

    11.对替换的算式进行加减运算匹配

    12.调用加减运算函数对匹配到的对象进行处理

    13.用sub将结果替换括号内算式的匹配到的对象

    14.重复11、12、13直到没有匹配对象

    15、重复上述步骤,直到没有括号

    16.得到没有括号的算式后,只要再按照幂、乘除、加减步骤走

    17.得到结果

流程图

  我还发现python在处理运算时,会自动帮我们处理正负号,所以在匹配时不用太多的去关心数字前的正负号

        

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#题目:求得字符串里'1-2*((60-30+9*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'计算式的结果
 
 
import re
 
#匹配规则
brackets = re.compile('\(([^()]+)\)')
powers = re.compile('(\d+\.?\d*)\*\*(\-?\d+\.?\d*)')
mul_div = re.compile('(\-?\d+\.?\d*)([*/])(\-?\d+\.?\d*)')
add_cut = re.compile('(\-?\d+\.?\d*)([+\-])(\-?\d+\.?\d*)')
 
def powers_calculate(match_obj):
    '''
    处理幂运算
    :param match_obj: 需要处理的match对象
    :return:算式的结果
    '''
    mat_grs = match_obj.groups()
    n1 = float(mat_grs[0])
    n2 = float(mat_grs[1])
    return n1**n2
 
def mul_div_calculate(match_obj):
    '''
    处理乘除运算
    :param match_obj: 需要处理的match对象
    :return: 算式的结果
    '''
    mat_grs = match_obj.groups()
    n1 = float(mat_grs[0])
    n2 = float(mat_grs[2])
    if mat_grs[1] == '*':
        return n1*n2
    else:
        return n1/n2
 
def add_cut_calculate(match_obj):
    '''
    处理加减运算
    :param match_obj: 需要处理的match对象
    :return: 算式的结果
    '''
    mat_grs = match_obj.groups()
    n1 = float(mat_grs[0])
    n2 = float(mat_grs[2])
    if mat_grs[1] == '+':
        return n1+n2
    else:
        return n1-n2
 
 
#数据源
data_sour = '1-2*((60-30+9*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
 
# data_sour = input('请输入你要计算的算式:')
#==================================================================================
 
#匹配最底层的括号
brackets_match = brackets.search(data_sour)
 
#对匹配到的括号进行处理
while True:
    if brackets_match:                  #判断匹配成功与否
        print(brackets_match.group())   #(9-2*5/3+7/3*99/4*2998+10*568/14)
        mat_groups1 = brackets_match.groups()  #得到去括号的组的值,不过此时这里是元组
        print(mat_groups1)              #('9-2*5/3+7/3*99/4*2998+10*568/14',)
 
        #处理幂运算
        text = mat_groups1[0]      #得到最底层括号里的算式字符串
        powers_match = powers.search(text)  #匹配幂运算
        while True:
            if powers_match:                #判断匹配成功与否
                print(powers_match.group())
                ret1 = powers_calculate(powers_match) #调用幂运算函数
                print(ret1)
                text = re.sub(powers,str(ret1),text,1#把得到的幂运算结果替换匹配到的字符串
                powers_match = powers.search(text)      #对替换的字符串再次进行幂运算匹配
            else:
                break                        #匹配失败,就退出匹配幂运算的循环
 
        #处理乘除运算
        mul_div_match = mul_div.search(text)  #对处理幂运算后的字符串进行乘除运算匹配
        while True:
            if mul_div_match:                 #判断匹配成功与否
                print(mul_div_match.group())
                ret2 = mul_div_calculate(mul_div_match)  #调用乘除运算函数
                print(ret2)
                text = re.sub(mul_div,str(ret2),text,1#把得到的乘除运算结果替换匹配的字符串
                print(text)
                mul_div_match = mul_div.search(text)     #对处理后的字符串再进行乘除运算匹配
            else:
                break   #匹配失败,就退出匹配乘除运算的循环
 
        #处理加减运算
        add_cut_match = add_cut.search(text)    #对处理乘除后的字符串进行加减运算匹配
        while True:
            if add_cut_match:                   #判断匹配成功与否
                print(add_cut_match.group())
                ret3 = add_cut_calculate(add_cut_match)  #调用加减运算函数
                text = re.sub(add_cut,str(ret3),text,1#用得到的加减运算结果替换匹配的字符串
                print(text)
                add_cut_match = add_cut.search(text)  #对处理后的字符串再进行加减运算匹配
            else:
                break      #匹配失败,退出匹配加减运算的循环
 
        data_sour = re.sub(brackets,text,data_sour,1#把括号里的计算结果替换匹配的括号
        brackets_match = brackets.search(data_sour)   #再次对处理后字符串进行括号的匹配
 
    else:
        break     #匹配不到括号,就退出匹配括号的循环
 
#对处理括号完后的算式进行最后的运算
#幂
powers_match = powers.search(data_sour)
while True:
    if powers_match:
        ret1 = powers_calculate(powers_match)
        data_sour = re.sub(powers,str(ret1),data_sour,1)
        powers_match = powers.search(data_sour)
    else:
        break
 
#乘除
mul_div_match = mul_div.search(data_sour)
while True:
    if mul_div_match:
        ret1 = mul_div_calculate(mul_div_match)
        data_sour = re.sub(mul_div, str(ret1), data_sour, 1)
        mul_div_match = mul_div.search(data_sour)
    else:
        break
 
#加减
add_cut_match = add_cut.search(data_sour)
while True:
    if add_cut_match:
        ret1 = add_cut_calculate(add_cut_match)
        data_sour = re.sub(add_cut, str(ret1), data_sour, 1)
        add_cut_match = add_cut.search(data_sour)
    else:
        break
 
print('最后结果为:',data_sour)
 
#验证结果
data_sour = '1-2*((60-30+9*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
jieguo = eval(data_sour)
print('验证结果:',jieguo)

 



如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
posted @   财经知识狂魔  阅读(346)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示