c# 从一组数中随机抽取一定个数_用随机的方法算24点(python)

24点很早之前就想做把它做出来,但是自己想不出来啊。看了大佬的解法用了二叉树来表示算式,但是我还是觉得好难理解。于是我另辟蹊径,想到通过随机的方法将几个数字和符号揉在一起,直到算到24。其实和遍历挺像的,随机写的话好像更简单些。

首先看看结果:

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函数将其打乱,这是第一个随机过程。

然后命名为

。四个数中运算符一共有三个。于是这三个我用
表示,并且加减乘除的运算符都是随机抽取的,用了random库中choice函数,这是第二个随机过程。

或许你注意到了

这个变量也正在随机,没错这是第三个随机过程。为什么要直接随机选取这几个情况呢?那是因为在做24点计算的时候我们往往可能会添加一些括号,导致了本来的先乘除后加减的运算优先级发生了改变。至于这些情况是怎么来的,不得不说随机的问题之一,我们必须确保随机能够随机到所有的情况。而所有的情况都要考虑到往往很难办到,尤其是一些犄角旮旯的地方。我不能保证这三种情况能够解所有能够解的24点问题,规律需要不断的总结,但是应该涵盖了大多数情况的。我总结的规律是这样的:

其中隐藏了运算符。

然后合并成为一个字符串。再用eval函数去点引号执行,都可以计算这个式子的值了。之后就是判断是否输出还是重新计算。判断我用了

bool型变量进行标识,是否循环就取决于这个变量,当得到24点的解的时候就改变它的值来中止循环。

主干部分分析完了,下面是为了这个程序更加好用而添加的。

  • 或许你留心到了record列表,这个列表的作用是将已经随机到的式子组合保存下来,下一次随机计算前先进行查表,有的话就不用计算了。这是为了加快计算速度,节省计算资源的。
  • 我还用time函数。这是因为并不是任意的四个数都能够算出24点。这个算法的弊端之二是不能肯定的说没有解。一般来说最慢0.2,0.3秒就可以计算完成,如果花了更长的时间还没有出来,那么说明没有解,或者上面情况少考虑了。所以我规定程序运行超过一秒钟就停止了。循环下面第一个if判断就是干这事的。
  • 你有发现留下的try语句吗?这是因为计算的时候可能会出现0除以0的情况,当出现这个情况的时候,程序就会报错,从而中止计算。所以就加了这样的语句,当出现这总情况的时候,跳出本次循环。
  • #print(shizi,'=',res),这条语句是个注释,如果我把这个注释去掉有什么效果,等下就知道了。
  • del ls,a,b,c,d 这句删除这些变量。因为别的不太清楚,python的列表用‘=’只是指向另一块内存,原来的数据还在。所以不clear或者删除的话,计算量大的话,可能会造成性能下降。

4e678be734cd77fd22c658effad6563f.png

这个就是去掉那条注释后的运行情况,不过别忘了把时间改大一点,因为print很耗时间的。比如说这个就超过了一秒。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值