python_四则运算改进版(去掉括号无用化)
GitHub的项目地址
【小学生的四则运算】--PSP表格
PSP2.1 |
任务内容 |
计划完成需要的时间(min) |
实际完成需要的时间(min) |
Planning |
计划 |
300 |
180 |
Estimate |
估计这个任务需要多少时间,并规划大致工作步骤 |
60 |
90 |
Development |
开发 |
100 |
80 |
Analysis |
需求分析 (包括学习新技术) |
60 |
30 |
Design Spec |
生成设计文档 |
10 |
5 |
Design Review |
设计复审 (和同事审核设计文档) |
30 |
20 |
Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
100 |
40 |
Design |
具体设计 |
100 |
120 |
Coding |
具体编码 |
300 |
200 |
Code Review |
代码复审 |
30 |
30 |
est |
测试(自我测试,修改代码,提交修改) |
60 |
100 |
Reporting |
报告 |
120 |
100 |
Test Report |
测试报告 |
60 |
50 |
Size Measurement |
计算工作量 |
30 |
20 |
Postmortem & Process Improvement Plan |
事后总结 ,并提出过程改进计划 |
60 |
80 |
Summary |
合计 |
1420 |
1045 |
项目要求
根据上个四则运算的项目把无效化括号去除
思路描述
四则运算括号无用性判断:
主要判断方法:
对比各个符号之间的优先级,很明显 *和/ 明显高于 -和+
外面的优先级高于里面的优先级时,则为有效括号,否则为无用括号
但有特殊情况,如1-(1-2),1/(1/2)这两种左边为减号或者除号的特殊情况则为有用符号
如何解决
括号的出现主要分为两类:1、开始出现括号;2、中间出现括号
1、如(1+4)+7、(1*2)+1等
主要比较括号里的符号和右括号右边符号的优先级,括号里的优先级高于右括号右边符号的优先级,则为无用括号
2、如1+(1+2)-1,2*(1*2)+1,1-(2*3)*1,1+(1+3*2)+2等
主要分为两种,第一种比较括号里的符号和左括号的左边符号的优先级,第二种括号里的符号和右括号的右边符号的优先级
第一种除了比较优先级,还要注意上述的两种特殊情况
第二种则和开始出现括号一种
只要两种情况满足其中一种,则为有效括号
具体程序设计
公共变量
变量 | 类型 | 作用 |
p1 | int | 存储左括号左边的符号 |
p2 | int | 存储右括号右边的符号 |
que | list | 存储表达式中每组括号的有用性 |
函数
函数名 | 作用 |
integer(n) |
随机产生几个表达式 |
judge(f, ch) |
判断表达式中的每个括号是否有用 |
代码说明
#integer 函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 def integer(): 2 ch = [] #存储表达式 3 number = random.randint(1, 5) #随机产生表达式的数量 4 for i in range(number): 5 rand = random.randint(0, 1) #随机产生0和1 判断是否使用括号 6 a = func_integer(number) #调用表达式产生函数,产生表达式 7 if rand == 0: 8 op = operation[random.randint(0,3)] #产生*,/来连接有括号的表达式,避免产生+,— 9 rand = random.randint(0, 1) #随机产生0和1 判断是否使用内嵌括号或外嵌括号 10 if i != number - 1: #避免开始和结尾用无意义的括号 11 if rand == 0: 12 ch.append('(') 13 ch.append(a) 14 ch.append(op) 15 ch.append(random.randint(1,10)) 16 ch.append(')') 17 ch.append(operation[random.randint(0, 3)]) 18 else: 19 ch.append(a) 20 ch.append(operation[random.randint(0, 3)]) 21 else: 22 ch.append(a) 23 ch.append(operation[random.randint(0, 3)]) 24 else: 25 ch.append(a) 26 ch.append(operation[random.randint(0, 3)]) 27 28 kuohao = [] 29 f = '' 30 for k,i in enumerate(ch): #把列表中的所有值用f一个个连起来 31 if k != len(ch)-1: 32 f += str(i) 33 for i in f: 34 if i.isdigit() == False: 35 if i == '+': 36 kuohao.append(0) 37 elif i == '-': 38 kuohao.append(1) 39 elif i == '*': 40 kuohao.append(2) 41 elif i == '/': 42 kuohao.append(3) 43 else: 44 kuohao.append(i) 45 result_integer(f, ch, kuohao)
#judge函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 def judge(f, ch): 2 p1 = -1 #左括号的左符号 3 p2 = -1 #右括号的右符号 4 que = [] #判断各组符号是否为有用,False为无用,True为有用 5 for k, i in enumerate(ch): 6 p = [] #存储括号中的符号 7 if i == '(' and k == 0: #开始出现括号 8 for j in range(1, len(ch)): 9 if ch[j] != '(' and ch[j] != ')' and ch[j] >= 0: 10 p.append(ch[j]) #ch[j]为括号中间的符号 11 elif ch[j] == ')': 12 for n in range(j + 1, len(ch)): 13 if ch[n] != ')' and ch[n] >= 0: 14 p2 = ch[n] #右括号的符号 15 break 16 else: 17 continue 18 break 19 else: 20 continue 21 #分两种情况,判断中间的括号的符号有几个符号 22 if len(p) == 1: #括号中间只有一个符号时 23 if (p[-1] == 0 or p[-1] == 1) and (p2 == 0 or p2 == 1): #括号中间符号为—或+时,右括号右边为—或+,为无用括号 24 que.append(False) 25 elif (p[-1] == 2 or p[-1] == 3): #括号中间符号为*或/时,为无用括号 26 que.append(False) 27 else: #其他的情况为有用括号 28 que.append(True) 29 if len(p) > 1: #括号中间不只符号时 30 if p2 == 0 or p2 == 1: #当右边符号为-或+,为无用符号 31 que.append(False) 32 elif (p2 == 3 or p2 == 4) and (0 not in p or 1 not in p): #当右括号右边的符号为*或/, 33 que.append(False) # 中间括号里没有+或-,则为无用符号 34 else: 35 que.append(True) 36 # 括号在中间的情况 37 if i == '(' and k != 0: 38 p1 = ch[k - 1] #左括号左边的符号 39 for j in range(k + 1, len(ch)): 40 if ch[j] != '(' and ch[j] != ')' and ch[j] >= 0: 41 p.append(ch[j]) #中间的符号 42 elif ch[j] == ')': 43 if j != len(ch) - 1: #判断右括号右边是否有符号 44 for n in range(j + 1, len(ch)): 45 if ch[n] != ')' and ch[n] >= 0: 46 p2 = ch[n] #右括号右边的符号 47 break 48 else: 49 continue 50 break 51 else: 52 p2 = -1 #右括号右边没有符号 53 else: 54 continue 55 #中间括号只有一个符号的情况 56 if len(p) == 1: 57 if p1 == 3: #左括号左边为/,都为有用括号 58 que.append(True) 59 elif p1 == 2 and (0 == p[-1] or 1 == p[-1]): #左括号为*,中间括号为-或+,为有用括号 60 que.append(True) 61 elif p1 == 1 and (0 == p[-1] or 1 == p[-1]): #左括号为-,中间的括号为-或+,为有用括号 62 que.append(True) 63 elif p1 == 0 and (0 == p[-1] or 1 == p[-1]) and (p2 == 3 or p2 ==2): 64 que.append(True) #左括号为+,中间括号为-或+,右括号为*或/ 65 else: 66 que.append(False) #其他情况为无用括号 67 #中间括号不只一个的情况 68 else: 69 if p1 == 3: #左括号左边为/,都为有用括号 70 que.append(True) 71 elif p1 == 1 and (1 in p or 0 in p): #左括号为-,中间的括号有-或+,为有用括号 72 que.append(True) 73 elif p1 == 2 and (0 in p or 1 in p): #左括号为*,中间括号有-或+,为有用括号 74 que.append(True) 75 elif p1 == 0 and (0 in p or 1 in p) and (p2 == 3 or p2 ==2): 76 que.append(True) #左括号为+,中间括号有-或+,右括号为*或/ 77 else: 78 que.append(False) 79 return que
代码运行如下
性能检测
总结及收获
本次项目虽然改进要求并不难,但是去除无用括号中的一些细节我没有想到,也把一些某个有用括号当无用的去掉了,但这种情况并不普遍。
这次的改进我能做好每个函数的性能测试及优化
这个项目过程也可谓是坎坷不断。
因为我个人现在能力问题和一点点地个人时间问题,这项目代码还有很多需要改进的地方,例如不把有用括号当无用括号除去等等,我都没能很好的解决。
还有很多需要改进的地方,以后再做补充。