博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
My first python program--填运算符问题的实现
阅读量:4339 次
发布时间:2019-06-07

本文共 4361 字,大约阅读时间需要 14 分钟。

问题:给定若干个整数opnum[1] opnum[2] ... opnum[N-1]作为操作数,按如下方式进行运算

得到一个期望结果值desired_result:

opnum[0] op[0] opnum[1] ... op[N-2] opnum[N-1] = desired_result
其中op[i]仅限于加减乘除,而且不使用括号。
在给定opnum[i]和desired_result的条件下,试求出op[i]的可能组合。
每种操作符号使用次数不限。假设运算仅限于整数域中。

分析:

1. 基本算法
由于要给出所有可能组合,所以最基本的方法就是穷举法。如果输入操作数为N(>=2)个,则操作符号
为N-1个,共有pow(4,N-1)种组合。
2. 运算优先度
由于乘和除的运算优先度高于加和减,所以对于每一种可能的运算表达式(共有pow(4,N-1)种组合),
不能单纯从左向右进行运算。要优先进行乘法和除法运算。所以在每次从左向右扫描时,表达式中的加法
或减法运算符只有当其右边不是乘或者除,或者本身已经是最后一个运算符时才应该被执行。
每个运算符都被执行后,最后比较运算结果是否与期望结果吻合以判断该运算组合是否为一个解。
3. 运算数据和操作符的存储
3-1 在初始状态,运算数据存储在N个单元(e.g, sequence or list)中,N-1个操作符存储在
N-1个单元中。
3-2 每个运算会导致运算数据减少一个,运算操作符也减少一个。可以考虑每执行一次运算即调整一次
操作数和操作运算符的存储调整,调整的方式是将后面的操作数和操作符往前挪一格,使得操作数和操
作符总是连续地排在前面几个存储单元中。基于这种存储及调节方式,可以知道第k个运算符相关联的
左操作数和右操作数分别是第k个操作数和第k+1个操作数。

1 import random 2  3 opsym = ['+','-','*','/'] # Only for final result logging. 4  5 ##在一定范围内随机生成若干个操作数以及期望结果(也可改为在运行时以交互方式输入,与后面的算法 6 ##实现相对独立) 7 numOfOpnum = 5 #random.randrange(2,5); # 暂时考虑固定5个操作数. 8  9 opnum = []10 11 for i in range(numOfOpnum):12     opnum.append(random.randrange(1,20))13 14 #-保留原始备份,因为opnum在以下处理会被改变。But "opnum_bak=opnum" doesn't work. Do you know why?    15 opnum_bak = opnum.copy();16 17 desiredRslt = random.randrange(1,20)18 19 for i in range(4**(numOfOpnum-1)):    20     opnum = opnum_bak.copy()    21     # 生成第i种运算操作符组合,分别以0,1,2,3代表加减乘除.22     op    = []23     quotient = i;24     for j in range(numOfOpnum-1):        25         op.append(quotient%4); 26         quotient = quotient//4; #‘//’表示整数除法27 28     op_bak = op.copy();    29 30     # 进入循环处理直到最后只剩下1个操作数(或者0个操作符)为止,最后剩下的操作数就是运算结果。31     while len(op) > 0:32         # 按顺序遍历剩下的运算符,符合条件即进行相应运算。每次循环只做碰到的第一次合法运算,33         # 运算完毕重新调整opnum和op(分别删除一个操作数和一个操作符),然后退回到上一级循环。34         # 但是list对象没有从中间任意位置删除某一项的method!怎么办呢?slice+concatenation!35         for j in range(len(op)):            36             if j == (len(op)-1):37                 if op[j] == 0:38                     opnum[j] = opnum[j] + opnum[j+1]; #执行运算并将结果存回opnum[j].39                     opnum.pop(); #这种情况下已知是删除末尾的所以可以用pop()。下同。40                     op.pop();41                     break42                 elif op[j]==1:    43                     opnum[j] = opnum[j] - opnum[j+1]; 44                     opnum.pop(); 45                     op.pop();46                     break47                 elif op[j]==2:    48                     opnum[j] = opnum[j] * opnum[j+1]; 49                     opnum.pop(); 50                     op.pop();51                     break52                 else: #op[j]==353                     opnum[j] = opnum[j] // opnum[j+1]; #整除!54                     opnum.pop(); 55                     op.pop();56                     break    57             else:58                 if op[j] == 2:59                     opnum[j] = opnum[j] * opnum[j+1]; 60                     opnum = opnum[0:j+1]+opnum[j+2:]; # remove opnum[j+1].61                     op    = op[0:j]+op[j+1:]; # remove op[j].62                     break63                 elif op[j] == 3:64                     opnum[j] = opnum[j] // opnum[j+1]; 65                     opnum = opnum[0:j+1]+opnum[j+2:]; # remove opnum[j+1].66                     op    = op[0:j]+op[j+1:]; # remove op[j].67                     break68                 elif op[j] == 0 and op[j+1]<2: #后面跟的不是乘或除时才执行对应运算。69                     opnum[j] = opnum[j] + opnum[j+1]; 70                     opnum = opnum[0:j+1]+opnum[j+2:]; # remove opnum[j+1].71                     op    = op[0:j]+op[j+1:]; # remove op[j].72                     break73                 elif op[j] == 1 and op[j+1]<2: #后面跟的不是乘或除时才执行对应运算。74                     opnum[j] = opnum[j] - opnum[j+1]; 75                     opnum = opnum[0:j+1]+opnum[j+2:]; # remove opnum[j+1].76                     op    = op[0:j]+op[j+1:]; # remove op[j].77                     break78                 else:79                     pass80                 81 82     # 打印当前运算符号组合的结果83     if opnum[0] == desiredRslt:84         print(opnum_bak[0],opsym[op_bak[0]],opnum_bak[1],opsym[op_bak[1]],opnum_bak[2],opsym[op_bak[2]],opnum_bak[3],opsym[op_bak[3]],opnum_bak[4],'=',desiredRslt,':OK' );85     else:86         print(opnum_bak[0],opsym[op_bak[0]],opnum_bak[1],opsym[op_bak[1]],opnum_bak[2],opsym[op_bak[2]],opnum_bak[3],opsym[op_bak[3]],opnum_bak[4],'!=',desiredRslt,':NG' );

 

 

转载于:https://www.cnblogs.com/iSlowRunner/p/3365911.html

你可能感兴趣的文章
图论知识,博客
查看>>
[原创]一篇无关技术的小日记(仅作暂存)
查看>>
20145303刘俊谦 Exp7 网络欺诈技术防范
查看>>
原生和jQuery的ajax用法
查看>>
iOS开发播放文本
查看>>
20145202马超《java》实验5
查看>>
JQuery 事件
查看>>
main(argc,argv[])
查看>>
第四阶段 15_Linux tomcat安装与配置
查看>>
NAS 创建大文件
查看>>
学习笔记-模块之xml文件处理
查看>>
接口测试用例
查看>>
面试:用 Java 实现一个 Singleton 模式
查看>>
Sybase IQ导出文件的几种方式
查看>>
案例:手动输入一个字符串,打散放进一个列表,小写字母反序 大写字母保持不变...
查看>>
linux 系统下 tar 的压缩与解压缩命令
查看>>
阿里负载均衡,配置中间证书问题(在starcom申请免费DV ssl)
查看>>
转:How to force a wordbreaker to be used in Sharepoint Search
查看>>
MySQL存储过程定时任务
查看>>
Python中and(逻辑与)计算法则
查看>>