核心思想:1.先考虑没有括号的式子如何进行运算,然后考虑正则匹配有括号的式子,通过逐步替换
利用正则计算:1 - 2 * ( (60-30 +(-40/5) * 20) - (-4*3)/ (16-3*2) )
# 方案1
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
|
#!/usr/bin/env python # -*- coding:utf-8 -*-
# author: Learning time:2018/4/30
import
re
# 定义一个乘除运算函数,最终返回一个运算结果
def
mul_div(cal):
if
'*'
in
cal:
x, y
=
cal.split(
'*'
)
return
float
(x)
*
float
(y)
if
'/'
in
cal:
x, y
=
cal.split(
'/'
)
return
float
(x)
/
float
(y)
# 定义一个处理加减符号的函数,这步是由于乘除运算完可能为负导致的
def
proce_symbol(cal):
cal
=
cal.replace(
'++'
,
'+'
)
cal
=
cal.replace(
'+-'
,
'-'
)
cal
=
cal.replace(
'--'
,
'+'
)
cal
=
cal.replace(
'-+'
,
'-'
)
return
cal
# 定义一个对内层没有括号的公式进行运算的函数,最终返回一个结果
def
inner(content):
"""
这步对内层的乘除进行循环处理,直到里面没有了乘除运算,全部替换成了结果
:param content:
:type content:
:return: 一个不带括号的运算式的结果
:rtype:
"""
# 浮点型匹配整数和浮点数啊哥,不是整数匹配浮点数
# 最后变成这样1-2*-128.8,要注意这里的正则匹配
con
=
re.search(r
'\d+\.?\d*[*/]\-?\d+\.?\d*'
, content)
while
con:
# 如果当中有乘除号
con
=
con.group()
temp
=
mul_div(con)
# 得到结果
content
=
content.replace(con,
str
(temp))
# 对内层运算式进行替换
content
=
proce_symbol(content)
#替换计算式中的乘除运算,直到替换完,对于冲突的+-号也进行替换
return
inner(content)
# 通过循环一直运算式中的乘除运算计算完
else
:
# 如果没有乘除号
# 对加减进行运算处理,把他们整到列表里面,挨个进行处理计算
lis
=
re.findall(r
'[+-]?\d+\.?\d*'
, content)
if
len
(lis)>
0
:
total_num
=
0
for
i
in
lis:
total_num
+
=
float
(i)
return
total_num
else
:
return
lis[
0
]
# 匹配最内层的括号
def
pars(cal):
"""
定义一个计算最内层运算的函数
:param cal:
:type cal:
:return:最能层运算
:rtype:
"""
par
=
re.search(
'\(([^()]*)\)'
, cal)
while
par:
# 如果当中有括号
content
=
par.group()
# (-40/5)
temp
=
inner(content.strip(
'()'
))
# 去括号,并处理结果-8
cal
=
cal.replace(content,
str
(temp))
return
pars(cal)
# 判断里面的运算符,可以有加减乘除
else
:
ret
=
inner(cal)
# 如果没有括号
return
ret
a
=
input
(
'计算式:'
).strip()
# 去除空格处理,得到1-2*((60-30+(-40/5)*20)-(-4*3)/(16-3*2))
a
=
re.sub(
'\s'
,'', a)
print
(pars(a))
|
方案2:
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
|
import
re
def
cal(exp):
if
'*'
in
exp:
a,b
=
exp.split(
'*'
)
return
str
(
float
(a)
*
float
(b))
elif
'/'
in
exp:
a, b
=
exp.split(
'/'
)
return
str
(
float
(a)
/
float
(b))
def
format
(exp):
exp
=
exp.replace(
'++'
,
"+"
)
exp
=
exp.replace(
'-+'
,
"-"
)
exp
=
exp.replace(
'+-'
,
"-"
)
exp
=
exp.replace(
'--'
,
"+"
)
return
exp
def
dealwith(no_bracket_exp):
# 匹配乘除法
while
True
:
mul_div
=
re.search(
'\d+(\.?\d+)?[*/]-?\d+(\.?\d+)?'
, no_bracket_exp)
if
mul_div:
exp
=
mul_div.group()
result
=
cal(exp)
no_bracket_exp
=
no_bracket_exp.replace(exp, result,
1
)
# (-8)
else
:
break
no_bracket_exp
=
format
(no_bracket_exp)
# 计算加减法
lst
=
re.findall(r
'[-+]?\d+(?:\.\d+)?'
, no_bracket_exp)
res
=
str
(
sum
([
float
(i)
for
i
in
lst]))
return
res
# 返回一个计算完毕的字符串数据类型的 数字
def
remove_bracket(s):
s
=
s.replace(
' '
, '')
# 去掉空格
while
True
:
ret
=
re.search(r
'\([^()]+\)'
, s)
# 匹配最内层的括号
if
ret:
# 能匹配到括号 就先处理括号内的加减乘除
no_bracket_exp
=
ret.group()
# 拿到括号中的表达式
ret
=
dealwith(no_bracket_exp)
# 把括号中的表达式交给的dealwith
s
=
s.replace(no_bracket_exp, ret,
1
)
else
:
# 不能匹配到括号 就字节处理加减乘除
ret
=
dealwith(s)
# 把表达式交给的dealwith
return
ret
s
=
'1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
print
(remove_bracket(s))
|
和方案二一样:
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
|
a
=
'1 - 2 * ( (60-30 +(-40/5) * 20) - (-4*3)/ (16-3*2) )'
import
re
new_a
=
re.sub(
' '
,'',a)
# 去括号处理
def
proce_symbol(cal):
# 去重复加减号
if
'++'
in
cal:cal
=
cal.replace(
'++'
,
'+'
)
if
'+-'
in
cal:cal
=
cal.replace(
'+-'
,
'-'
)
if
'--'
in
cal:cal
=
cal.replace(
'--'
,
'+'
)
if
'-+'
in
cal:cal
=
cal.replace(
'-+'
,
'-'
)
return
cal
def
mul_div(famula):
if
'*'
in
famula:
num1, num2
=
famula.split(
'*'
)
total
=
str
(
float
(num1)
*
float
(num2))
return
total
if
'/'
in
famula:
num1, num2
=
famula.split(
'/'
)
total
=
str
(
float
(num1)
/
float
(num2))
return
total
def
total(famula):
while
True
:
if
'*'
or
'/'
in
famula:
num
=
re.search(r
'\d+(\.?\d+)?[*/]\-?\d+(\.?\d+)?'
,famula)
if
num:
num
=
num.group()
nums
=
mul_div(num)
famula
=
famula.replace(num, nums,
1
)
famula
=
proce_symbol(famula)
# 如果算式中剩下加减运算
else
:
lis
=
re.findall(r
'[-]?\d+(?:\.?\d+)?'
,famula)
sums
=
sum
([
float
(i)
for
i
in
lis])
return
sums
def
bras(famu):
while
True
:
bra
=
re.search(
'\([^()]+\)'
,famu)
# 获取括号内的内容
if
bra:
bra
=
bra.group()
ret
=
total(bra)
famu
=
famu.replace(bra,
str
(ret),
1
)
s
=
proce_symbol(famu)
return
bras(s)
else
:
s
=
proce_symbol(famu)
ret
=
total(s)
return
ret
print
(bras(new_a))
|
核心思想:1.先考虑没有括号的式子如何进行运算,然后考虑正则匹配有括号的式子,通过逐步替换
利用正则计算:1 - 2 * ( (60-30 +(-40/5) * 20) - (-4*3)/ (16-3*2) )
# 方案1
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
|
#!/usr/bin/env python # -*- coding:utf-8 -*-
# author: Learning time:2018/4/30
import
re
# 定义一个乘除运算函数,最终返回一个运算结果
def
mul_div(cal):
if
'*'
in
cal:
x, y
=
cal.split(
'*'
)
return
float
(x)
*
float
(y)
if
'/'
in
cal:
x, y
=
cal.split(
'/'
)
return
float
(x)
/
float
(y)
# 定义一个处理加减符号的函数,这步是由于乘除运算完可能为负导致的
def
proce_symbol(cal):
cal
=
cal.replace(
'++'
,
'+'
)
cal
=
cal.replace(
'+-'
,
'-'
)
cal
=
cal.replace(
'--'
,
'+'
)
cal
=
cal.replace(
'-+'
,
'-'
)
return
cal
# 定义一个对内层没有括号的公式进行运算的函数,最终返回一个结果
def
inner(content):
"""
这步对内层的乘除进行循环处理,直到里面没有了乘除运算,全部替换成了结果
:param content:
:type content:
:return: 一个不带括号的运算式的结果
:rtype:
"""
# 浮点型匹配整数和浮点数啊哥,不是整数匹配浮点数
# 最后变成这样1-2*-128.8,要注意这里的正则匹配
con
=
re.search(r
'\d+\.?\d*[*/]\-?\d+\.?\d*'
, content)
while
con:
# 如果当中有乘除号
con
=
con.group()
temp
=
mul_div(con)
# 得到结果
content
=
content.replace(con,
str
(temp))
# 对内层运算式进行替换
content
=
proce_symbol(content)
#替换计算式中的乘除运算,直到替换完,对于冲突的+-号也进行替换
return
inner(content)
# 通过循环一直运算式中的乘除运算计算完
else
:
# 如果没有乘除号
# 对加减进行运算处理,把他们整到列表里面,挨个进行处理计算
lis
=
re.findall(r
'[+-]?\d+\.?\d*'
, content)
if
len
(lis)>
0
:
total_num
=
0
for
i
in
lis:
total_num
+
=
float
(i)
return
total_num
else
:
return
lis[
0
]
# 匹配最内层的括号
def
pars(cal):
"""
定义一个计算最内层运算的函数
:param cal:
:type cal:
:return:最能层运算
:rtype:
"""
par
=
re.search(
'\(([^()]*)\)'
, cal)
while
par:
# 如果当中有括号
content
=
par.group()
# (-40/5)
temp
=
inner(content.strip(
'()'
))
# 去括号,并处理结果-8
cal
=
cal.replace(content,
str
(temp))
return
pars(cal)
# 判断里面的运算符,可以有加减乘除
else
:
ret
=
inner(cal)
# 如果没有括号
return
ret
a
=
input
(
'计算式:'
).strip()
# 去除空格处理,得到1-2*((60-30+(-40/5)*20)-(-4*3)/(16-3*2))
a
=
re.sub(
'\s'
,'', a)
print
(pars(a))
|
方案2:
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
|
import
re
def
cal(exp):
if
'*'
in
exp:
a,b
=
exp.split(
'*'
)
return
str
(
float
(a)
*
float
(b))
elif
'/'
in
exp:
a, b
=
exp.split(
'/'
)
return
str
(
float
(a)
/
float
(b))
def
format
(exp):
exp
=
exp.replace(
'++'
,
"+"
)
exp
=
exp.replace(
'-+'
,
"-"
)
exp
=
exp.replace(
'+-'
,
"-"
)
exp
=
exp.replace(
'--'
,
"+"
)
return
exp
def
dealwith(no_bracket_exp):
# 匹配乘除法
while
True
:
mul_div
=
re.search(
'\d+(\.?\d+)?[*/]-?\d+(\.?\d+)?'
, no_bracket_exp)
if
mul_div:
exp
=
mul_div.group()
result
=
cal(exp)
no_bracket_exp
=
no_bracket_exp.replace(exp, result,
1
)
# (-8)
else
:
break
no_bracket_exp
=
format
(no_bracket_exp)
# 计算加减法
lst
=
re.findall(r
'[-+]?\d+(?:\.\d+)?'
, no_bracket_exp)
res
=
str
(
sum
([
float
(i)
for
i
in
lst]))
return
res
# 返回一个计算完毕的字符串数据类型的 数字
def
remove_bracket(s):
s
=
s.replace(
' '
, '')
# 去掉空格
while
True
:
ret
=
re.search(r
'\([^()]+\)'
, s)
# 匹配最内层的括号
if
ret:
# 能匹配到括号 就先处理括号内的加减乘除
no_bracket_exp
=
ret.group()
# 拿到括号中的表达式
ret
=
dealwith(no_bracket_exp)
# 把括号中的表达式交给的dealwith
s
=
s.replace(no_bracket_exp, ret,
1
)
else
:
# 不能匹配到括号 就字节处理加减乘除
ret
=
dealwith(s)
# 把表达式交给的dealwith
return
ret
s
=
'1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
print
(remove_bracket(s))
|
和方案二一样:
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
|
a
=
'1 - 2 * ( (60-30 +(-40/5) * 20) - (-4*3)/ (16-3*2) )'
import
re
new_a
=
re.sub(
' '
,'',a)
# 去括号处理
def
proce_symbol(cal):
# 去重复加减号
if
'++'
in
cal:cal
=
cal.replace(
'++'
,
'+'
)
if
'+-'
in
cal:cal
=
cal.replace(
'+-'
,
'-'
)
if
'--'
in
cal:cal
=
cal.replace(
'--'
,
'+'
)
if
'-+'
in
cal:cal
=
cal.replace(
'-+'
,
'-'
)
return
cal
def
mul_div(famula):
if
'*'
in
famula:
num1, num2
=
famula.split(
'*'
)
total
=
str
(
float
(num1)
*
float
(num2))
return
total
if
'/'
in
famula:
num1, num2
=
famula.split(
'/'
)
total
=
str
(
float
(num1)
/
float
(num2))
return
total
def
total(famula):
while
True
:
if
'*'
or
'/'
in
famula:
num
=
re.search(r
'\d+(\.?\d+)?[*/]\-?\d+(\.?\d+)?'
,famula)
if
num:
num
=
num.group()
nums
=
mul_div(num)
famula
=
famula.replace(num, nums,
1
)
famula
=
proce_symbol(famula)
# 如果算式中剩下加减运算
else
:
lis
=
re.findall(r
'[-]?\d+(?:\.?\d+)?'
,famula)
sums
=
sum
([
float
(i)
for
i
in
lis])
return
sums
def
bras(famu):
while
True
:
bra
=
re.search(
'\([^()]+\)'
,famu)
# 获取括号内的内容
if
bra:
bra
=
bra.group()
ret
=
total(bra)
famu
=
famu.replace(bra,
str
(ret),
1
)
s
=
proce_symbol(famu)
return
bras(s)
else
:
s
=
proce_symbol(famu)
ret
=
total(s)
return
ret
print
(bras(new_a))
|