龙空技术网

python小练习之字符串四则运算式编码解题思路

皛心 45

前言:

现在小伙伴们对“python从字符串随机选取4个字符”大约比较着重,兄弟们都想要知道一些“python从字符串随机选取4个字符”的相关知识。那么小编在网络上收集了一些对于“python从字符串随机选取4个字符””的相关文章,希望兄弟们能喜欢,看官们一起来了解一下吧!

首先循环查找最内层括号,对其中的运算式求解,然后将结果替换掉字符串中对应的运算式。循环求解直到整个运算式所有括号均被解。

对不含括号的运算式求解时从左到右,先循环解出所有除法,再循环解出所有乘法,再做加减法。

解括号

首先看题目案例:

'10-3*(20-10+(-10/5)*27/3/3-(-100)/(10-3*5))+(-2.5*-12)'

首先要提取内层括号内的所有字符,编写正则表达式如下:

'\(([^()]+?)\)'

# \(和\)是为了匹配左括号和右括号,注意左右括号在正则表达式表示分组的意思,所以要加\转义成原本括号的意思。

# [^()]字符组内^表示非,^()表示匹配不含括号的内容

# +?表示匹配内容为1个或多个,最小匹配模式

# ([^()]+?)表示对不含括号的内容作为分组提取

编写解括号的代码:

def cal(s):

s = s.replace(' ', '') # 去除字符串中所有空格,防止匹配出错

while '(' in s or ')' in s:

ret = re.findall('\(([^()]+?)\)', s)

for i in ret:

s = s.replace(f'({i})', count(i)) # count函数用来计算不含括号的加减乘除运算式

s = s.replace('--', '+') # 注意一:处理解括号后可能出现减负号的情况

else:

s = count(s)

return s

解乘除

这里是计算不含括号的加减乘除运算式,首先要做除法,那么先要提取除法运算式左右两边的数字,编写正则表达式如下:

([-]?\d+\.\d+|[-]?\d+)/([-]?\d+\.\d+|[-]?\d+)

# [-]?表示可能存在负号

# \d+\.\d+表示匹配浮点数

# [-]?\d+表示匹配整数

# ([-]?\d+\.\d+|[-]?\d+)表示提取正负浮点数或正负整数

# ([-]?\d+\.\d+|[-]?\d+)/([-]?\d+\.\d+|[-]?\d+) 表示提取/两边的正负浮点数或正负整数

循环运算除法过程:

def count(s):

while '/' in s:

result = re.findall('([-]?\d+\.\d+|[-]?\d+)/([-]?\d+\.\d+|[-]?\d+)', s)

for i in result:

s = s.replace(f'{i[0]}/{i[1]}', f'{float(i[0]) / float(i[1])}')

循环运算乘法过程(乘法的正则和除法的正则只差一个运算符):

while '*' in s:

result = re.findall('([-]?\d+\.\d+|[-]?\d+)\*([-]?\d+\.\d+|[-]?\d+)', s)

for i in result:

if float(i[0]) < 0 and float(i[1]) < 0: # 注意二:负数乘负数得正数

s = s.replace(f'{i[0]}*{i[1]}', f'+{float(i[0]) * float(i[1])}')

else:

s = s.replace(f'{i[0]}*{i[1]}', f'{float(i[0]) * float(i[1])}')

解加减法

解加减法的感觉是最简单的一步,只要按上面的正则匹配出正负浮点数或正负整数,然后对所有数值累加即可。

result = re.findall('([-]?\d+\.\d+|[-]?\d+)', s)

x = 0

for i in result:

x += float(i)

s = str(x)

return s

完整代码

import re

def count(s):

while '/' in s:

result = re.findall('([-]?\d+\.\d+|[-]?\d+)/([-]?\d+\.\d+|[-]?\d+)', s)

for i in result:

s = s.replace(f'{i[0]}/{i[1]}', f'{float(i[0]) / float(i[1])}')

while '*' in s:

result = re.findall('([-]?\d+\.\d+|[-]?\d+)\*([-]?\d+\.\d+|[-]?\d+)', s)

for i in result:

if float(i[0]) < 0 and float(i[1]) < 0:

s = s.replace(f'{i[0]}*{i[1]}', f'+{float(i[0]) * float(i[1])}')

else:

s = s.replace(f'{i[0]}*{i[1]}', f'{float(i[0]) * float(i[1])}')

result = re.findall('([-]?\d+\.\d+|[-]?\d+)', s)

x = 0

for i in result:

x += float(i)

s = str(x)

return s

def cal(s):

s = s.replace(' ', '')

while '(' in s or ')' in s:

ret = re.findall('\(([^()]+?)\)', s)

for i in ret:

s = s.replace(f'({i})', count(i))

s = s.replace('--', '+')

else:

s = count(s)

return s

print(cal('10-3*(20-10+(-10/5)*27/3/3-(-100)/(10-3*5))'))

print(cal('10-3*(20-10+(-10/5)*27/3/3-(-100)/(10-3*5))+(-2.5*-12)'))

print(cal('10 - 3 * ( (50-30 +(-10/5) * (9-2*5/3 + 7 /3*99/4*2020 +10 * 789/15 )) - (-4*3)/ (16-3*2) )'))

out:

58.0

88.0

703066.4000000001

注意事项

注意一:处理解括号后可能出现减负号的情况。

注意二:负数乘负数得正数。

上述两条注意事项在编码时并未考虑到,后来运行程序发现结果不对,调试了很久才发现上述2个注意事项被忽略了,最后加上了2行代码后运算结果正确无误。

基本四则运算已经都非常熟悉了,但编码过程中还是会有疏漏。这在编写项目时经常会发生类似情况。程序员和需求方沟通时经常会发生类似情况,需求方经常因为有些是常识性的细节忘了提及,而程序员不精通业务需求方的业务,此时在需求方未提及的细节程序员也未考虑周全就会产生疏漏和bug。

所以加强沟通非常重要,程序员考虑需求全面且细致非常重要。

标签: #python从字符串随机选取4个字符