• 洗牌问题


    题目内容

    题目: 手里面n张不同牌面的牌,编写一个洗牌程序,让随机取出一张牌的概率相同。

    要求: 说明算法思路、分析时间复杂度、用Array编写洗牌程序、编写测试用例。

    算法思路

    image.png

    时间复杂度


      时间复杂度应该为:O(n)

    实现程序

    下面给出4种实现方法、比较各种方法的好坏,其中shuffle_best(cards)是上面算法分析的实现。

    import random
    def shuffle_system(cards):
        random.shuffle(cards)  # 官方给你的shuffle函数
    
    import random
    def shuffle_1st(cards):
        for k in range(len(cards)):
            i = random.randint(0,len(cards)-1) # 随机取出一张
            j = random.randint(0,len(cards)-1) # 随机取出一张
            cards[i], cards[j] = cards[j], cards[i] # 两张交换
    
    import random
    def shuffle_2nd(cards):
        for k in range(len(cards)):
            i = random.randint(0,len(cards)-1) # 随机取出一张
            cards[i], cards[k] = cards[k], cards[i] # 两张交换
        
    

    最好的解法:
         randomi =  i + random.randint(0,(len(cards) - i -1)) ,此处 i +保证了前面放好的了牌不会被取到。

    import random
    def shuffle_best(cards):
        for i in range(len(cards)):  
            randomi =  i + random.randint(0,(len(cards) - i -1)) # 从剩下的随机取出一张
            cards[i], cards[randomi] = cards[randomi], cards[i] # 依次取出的和从剩余中随机取出的交换
       
    

    测试用例

    def test_shuffle(f):
        result = [[0 for i in range(0,10)] for j in range(0,10)]
        
        for i in range(10000):
            A = [i for i in range(0,10)]
            f(A)
            for j in range(len(A)):
                result[A[j]][j] += 1 # 第j张牌在第j个位置
        print("
    ".join([''.join(['{:6}'.format(item) for item in row])for row in result]))
    

    image.png
    用官方给出的shuffle接口,每张牌出现的概率大都为1/10,符合要求。
    image.png
    第一种洗牌程序,主对角线上的概率为2/10,不是很理想。
    image.png
    第二种洗牌程序,主对角线下面的元素也不是很理想,我们想要的是都在1000次左右。
    image.png
    第三种洗牌程序,每张牌在每个位置出现的位置的次数都接近1000,相比1st 和 2nd 的情况要好一点,是我们想要。


  • 相关阅读:
    删除maven本地库中下载不完全的jar包
    nginx负载均衡
    对字符串中的中英文进行统计
    springboot部分常用注解
    Scala 泛型
    Scala 递归举例
    Kafka(v0.11)笔记
    Scala 匿名函数与参数类型推断(简写)
    Scala 高阶函数
    Scala 偏函数 PartialFunction
  • 原文地址:https://www.cnblogs.com/sinlearn/p/12892126.html
Copyright © 2020-2023  润新知