《Automate the Boring Stuff》硬币连续投掷问题代码优化求助
你目前的代码实现了统计连续6次相同硬币投掷结果的功能,但存在一些逻辑问题和可以优化的点,下面逐一说明:
一、错误排查
循环范围遗漏
原代码中while i<9995,但实际上要检查从索引0到9995的起始位置(因为要取i-1到i+4共6个元素,当i=9995时,i+4=9999,刚好是列表最后一个元素),原条件会漏掉这最后一组检查,导致计数偏少。概率计算逻辑错误
原代码用numberOfStreaks / 100计算概率,但10000次投掷中,能形成连续6次的窗口总数是10000 - 6 + 1 = 9995个,正确的概率应该是(numberOfStreaks / 9995) * 100,原计算方式会导致结果偏差。streak 计数逻辑歧义
原代码中,连续7个相同结果会被计数2次(比如索引0-5和1-6),如果你的需求是统计独立的连续 streak 数量(即连续7个只算1次),那这个逻辑就不符合要求;如果是统计所有连续6次的出现窗口数,那逻辑没问题,但需要明确需求。
二、效率优化建议
无需预存完整投掷列表
可以一边生成硬币结果,一边统计连续次数,不用存储整个10000元素的列表,节省内存,尤其当数据量更大时优势明显。跟踪当前连续次数替代多元素比较
不用每次比较6个元素,而是维护一个变量记录当前连续相同结果的次数,每次新结果和前一个相同就加1,否则重置为1。当连续次数达到6时,根据需求计数(窗口式计数则每次加1,独立streak则只加一次并跳过后续重复计数)。简化硬币生成逻辑
用random.choice(['H', 'T'])直接生成投掷结果,替代randint加判断的写法,代码更简洁。
三、优化后代码示例
示例1:统计所有连续6次的窗口数(和原代码逻辑一致但优化)
import random def count_streaks(): streak_count = 0 current_streak = 1 # 生成第一个结果 last_flip = random.choice(['H', 'T']) for _ in range(9999): current_flip = random.choice(['H', 'T']) if current_flip == last_flip: current_streak += 1 # 当连续次数达到6及以上时,每多一次相同就多一个窗口 if current_streak >= 6: streak_count += 1 else: current_streak = 1 last_flip = current_flip # 计算正确概率 total_windows = 10000 - 6 + 1 probability = (streak_count / total_windows) * 100 print(f"连续6次的窗口数: {streak_count}") print(f"出现连续6次的概率: {probability:.2f}%") count_streaks()
示例2:统计独立的连续 streak 数量(连续7个只算1次)
import random def count_independent_streaks(): streak_count = 0 current_streak = 1 last_flip = random.choice(['H', 'T']) # 标记是否已经统计过当前 streak counted = False for _ in range(9999): current_flip = random.choice(['H', 'T']) if current_flip == last_flip: current_streak += 1 if current_streak >= 6 and not counted: streak_count += 1 counted = True else: current_streak = 1 counted = False last_flip = current_flip total_windows = 10000 - 6 + 1 probability = (streak_count / total_windows) * 100 print(f"独立连续6次的数量: {streak_count}") print(f"出现独立连续6次的概率: {probability:.2f}%") count_independent_streaks()
四、结果说明
从理论上来说,每次投掷出现连续6次相同结果的概率是2*(1/2)^6 = 1/32 ≈ 3.125%,随机试验的结果会在这个值附近波动,你的原代码结果3.37%属于合理范围。
内容的提问来源于stack exchange,提问作者Alex

