24点很早之前就想做把它做出来,但是自己想不出来啊。看了大佬的解法用了二叉树来表示算式,但是我还是觉得好难理解。于是我另辟蹊径,想到通过随机的方法将几个数字和符号揉在一起,直到算到24。其实和遍历挺像的,随机写的话好像更简单些。
首先看看结果:
![56d5e1205c8d2f04093e0e1bd4a9abc9.png](https://img-blog.csdnimg.cn/img_convert/56d5e1205c8d2f04093e0e1bd4a9abc9.png)
这是计算(1,5,5,5)的方法,虽然是随机,但速度也不慢。事实上我做了个查表功能也就是实际上所有的可能都只随机的一次。
下面附上全代码。
# 24point.py
from time import time
from random import shuffle, choice
def solve_twofour(num_list):
success = False
record = []
start = time()
while not success:
if int(time() - start) > 1:
print('no answer')
success = True
ls = num_list
shuffle(ls)
a = str(ls[0])
b = str(ls[1])
c = str(ls[2])
d = str(ls[3])
s1 = choice('+-*/')
s2 = choice('+-*/')
s3 = choice('+-*/')
shizi = choice(['(('+a+s1+b+')'+s2+c+')'+s3+d,
'('+a+s1+b+')'+s2+'('+c+s3+d+')',
'('+a+s1+'('+b+s2+c+'))'+s3+d])
if shizi in record:
continue
record.append(shizi)
try:
res = eval(shizi)
except:
continue
#print(shizi,'=',res)
if res == 24:
print(shizi)
success = True
del ls,a,b,c,d
start = time()
solve_twofour([1,5,5,5])
print('spend time:',time() - start)
通过阅读代码,加了许多额外的东西,比如时间的判断等等。先说主干部分。
这个函数需要一个装有你要计算的那4个数。然后我用random库的shuffle函数将其打乱,这是第一个随机过程。
然后命名为
或许你注意到了
其中隐藏了运算符。
然后合并成为一个字符串。再用eval函数去点引号执行,都可以计算这个式子的值了。之后就是判断是否输出还是重新计算。判断我用了
主干部分分析完了,下面是为了这个程序更加好用而添加的。
- 或许你留心到了record列表,这个列表的作用是将已经随机到的式子组合保存下来,下一次随机计算前先进行查表,有的话就不用计算了。这是为了加快计算速度,节省计算资源的。
- 我还用time函数。这是因为并不是任意的四个数都能够算出24点。这个算法的弊端之二是不能肯定的说没有解。一般来说最慢0.2,0.3秒就可以计算完成,如果花了更长的时间还没有出来,那么说明没有解,或者上面情况少考虑了。所以我规定程序运行超过一秒钟就停止了。循环下面第一个if判断就是干这事的。
- 你有发现留下的try语句吗?这是因为计算的时候可能会出现0除以0的情况,当出现这个情况的时候,程序就会报错,从而中止计算。所以就加了这样的语句,当出现这总情况的时候,跳出本次循环。
- #print(shizi,'=',res),这条语句是个注释,如果我把这个注释去掉有什么效果,等下就知道了。
- del ls,a,b,c,d 这句删除这些变量。因为别的不太清楚,python的列表用‘=’只是指向另一块内存,原来的数据还在。所以不clear或者删除的话,计算量大的话,可能会造成性能下降。
![4e678be734cd77fd22c658effad6563f.png](https://img-blog.csdnimg.cn/img_convert/4e678be734cd77fd22c658effad6563f.png)
这个就是去掉那条注释后的运行情况,不过别忘了把时间改大一点,因为print很耗时间的。比如说这个就超过了一秒。