鱼C论坛

 找回密码
 立即注册
查看: 238|回复: 4

[已解决]请问怎么优化统计抛硬币正反面代码

[复制链接]
发表于 2025-4-7 12:21:52 | 显示全部楼层 |阅读模式
3鱼币
做了课后练习题抛硬币统计,下面这个代码是我自己写的,请问能怎么优化,最好是能指出我的代码繁冗在哪里,谢谢!
import random
i=int(input("请输入抛硬币次数:"))
x=i #抛硬币总数
jz=0 #统计连续出现正面次数的标记
jzpd=0 #连续出现正面计数次数最多统计
jf=0 #统计连续出现反面次数的标记
jfpd=0 #连续出现反面计数次数最多统计
js1=0 #硬币正面出现次数计数
js2=0 #硬币反面出现次数计数
if i < 100:
    while i:
        j = random.randint(1,2)
        if j == 1:
            jf = 0 #当出现正面时,将连续出现反面次数标记归0
            print("正面",end=" ")
            jz += 1 #计数连续出现正面次数
            js1 += 1 #统计一共出现多少次正面
            if jz > jzpd:
                jzpd = jz #将连续出现正面次数的最高值赋予jzpd
        elif j == 2:
            jz = 0 #当出现正面时,将连续出现正面次数标记归0
            print("反面",end=" ")
            jf += 1 #计数连续出现反面次数
            js2 += 1 #统计一共出现多少次反面
            if jf > jfpd:
                jfpd = jf #将连续出现反面次数的最高值赋予jfpd
        i -= 1
else:
    while i:
        j = random.randint(1,2)
        if j == 1:
            jf = 0 #当出现正面时,将连续出现反面次数标记归0
            jz += 1 #计数连续出现正面次数
            js1 += 1 #统计一共出现多少次正面
            if jz > jzpd:
                jzpd = jz #将连续出现正面次数的最高值赋予jzpd
        elif j == 2:
            jz = 0 #当出现正面时,将连续出现正面次数标记归0
            jf += 1 #计数连续出现反面次数
            js2 += 1 #统计一共出现多少次反面
            if jf > jfpd:
                jfpd = jf #将连续出现反面次数的最高值赋予jfpd
        i -= 1
print(f"总共模拟了{x}次抛硬币")
print("正面次数=",js1)
print("反面次数=",js2)
print(f"连续出现正面次数最多时为{jzpd}次")
print(f"连续出现正反面次数最多时为{jfpd}次")
最佳答案
2025-4-7 12:21:53
本帖最后由 jackz007 于 2025-4-9 12:46 编辑
  1. import random
  2. n = int(input("请输入抛硬币次数:"))
  3. k , jz , jf , jzpd , jfpd = 0 , 0 , 0 , 0 , 0
  4. for _ in range(n) :
  5.     if random . randint(1 , 2) % 2 :               # 如果是正面
  6.         k += 1                                     # k - 正面总计数
  7.         if jf : jf = 0                             # 连续反面计数清零
  8.         jz += 1                                    # 连续正面计数增 1
  9.         if jz > jzpd : jzpd = jz                   # 如果连续正面计数超过记录,则更新记录
  10.         s = '【正面】'
  11.     else :
  12.         if jz : jz = 0                             # 连续正面计数清零
  13.         jf += 1                                    # 连续反面计数增 1
  14.         if jf > jfpd : jfpd = jf                   # 如果连续反面计数超过记录,则更新记录
  15.         s = '[反面]'
  16.     if n < 100 : print(s)                          # 如果抛币次数在 100 次以内,则打印每一次的抛币结果
  17. print('总共抛币【{}】次,其中:正面【{}】 次,反面 [{}] 次,最大连续正面【{}】次,最大连续反面 [{}] 次。' . format(n , k , n - k , jzpd , jfpd))
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2025-4-7 12:21:53 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2025-4-9 12:46 编辑
  1. import random
  2. n = int(input("请输入抛硬币次数:"))
  3. k , jz , jf , jzpd , jfpd = 0 , 0 , 0 , 0 , 0
  4. for _ in range(n) :
  5.     if random . randint(1 , 2) % 2 :               # 如果是正面
  6.         k += 1                                     # k - 正面总计数
  7.         if jf : jf = 0                             # 连续反面计数清零
  8.         jz += 1                                    # 连续正面计数增 1
  9.         if jz > jzpd : jzpd = jz                   # 如果连续正面计数超过记录,则更新记录
  10.         s = '【正面】'
  11.     else :
  12.         if jz : jz = 0                             # 连续正面计数清零
  13.         jf += 1                                    # 连续反面计数增 1
  14.         if jf > jfpd : jfpd = jf                   # 如果连续反面计数超过记录,则更新记录
  15.         s = '[反面]'
  16.     if n < 100 : print(s)                          # 如果抛币次数在 100 次以内,则打印每一次的抛币结果
  17. print('总共抛币【{}】次,其中:正面【{}】 次,反面 [{}] 次,最大连续正面【{}】次,最大连续反面 [{}] 次。' . format(n , k , n - k , jzpd , jfpd))
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2025-4-7 12:23:01 | 显示全部楼层

  1. import random

  2. total = int(input("请输入抛硬币次数:"))
  3. print_result = total < 100  # 是否打印每次结果

  4. # 初始化计数器
  5. heads = tails = 0
  6. current_heads = current_tails = 0
  7. max_heads = max_tails = 0

  8. for _ in range(total):
  9.     coin = random.choice(["正面", "反面"])  # 更直观的随机选择
  10.    
  11.     if coin == "正面":
  12.         heads += 1
  13.         current_heads += 1
  14.         current_tails = 0  # 重置反面连续计数
  15.         if current_heads > max_heads:
  16.             max_heads = current_heads
  17.     else:
  18.         tails += 1
  19.         current_tails += 1
  20.         current_heads = 0  # 重置正面连续计数
  21.         if current_tails > max_tails:
  22.             max_tails = current_tails
  23.    
  24.     if print_result:
  25.         print(coin, end=" ")

  26. print(f"\n总共模拟了{total}次抛硬币")
  27. print(f"正面次数: {heads}")
  28. print(f"反面次数: {tails}")
  29. print(f"连续出现正面次数最多时为{max_heads}次")
  30. print(f"连续出现反面次数最多时为{max_tails}次")
复制代码


优化说明:

1. 逻辑重复问题:原代码存在两个几乎相同的while循环,通过增加print_result判断合并为一个循环

2. 变量命名优化:使用更直观的变量名:
   - jzpd → max_heads
   - jfpd → max_tails
   - js1 → heads
   - js2 → tails

3. 简化随机逻辑:使用random.choice()直接返回"正面"/"反面"

4. 循环结构优化:改用for循环替代while,避免手动管理计数器

5. 减少重复代码:将正反面处理的公共逻辑合并,通过if-else统一管理

6. 输出优化:统一使用f-string格式化输出,增强可读性

原代码主要冗余点:
  • 重复的while循环结构(仅打印逻辑不同)
  • 多余的变量初始化(如x = i)
  • 手动管理循环计数器(i -= 1)
  • 两个几乎相同的条件分支结构


这个优化版本在保持原有功能完整的前提下,代码量减少约40%,逻辑更清晰易读。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2025-4-8 11:42:50 | 显示全部楼层
修改后的代码如下:

  1. import random
  2. def play:
  3.     i=input("请输入抛硬币次数:")
  4.     try:
  5.         w=int(i) #检测是否为整数
  6.         if "." in i: #如果是浮点数
  7.             a="FishC"+520 #强行报错,跳出try代码块   
  8.         jz=0 #统计连续出现正面次数的标记
  9.         jzpd=0 #连续出现正面计数次数最多统计
  10.         jf=0 #统计连续出现反面次数的标记
  11.         jfpd=0 #连续出现反面计数次数最多统计
  12.         js1=0 #硬币正面出现次数计数
  13.         js2=0 #硬币反面出现次数计数
  14.         if w < 100:
  15.             while w:
  16.                 j = random.randint(1,2)
  17.                 if j == 1:
  18.                     jf = 0 #当出现正面时,将连续出现反面次数标记归0
  19.                     print("正面",end=" ")
  20.                     jz += 1 #计数连续出现正面次数
  21.                     js1 += 1 #统计一共出现多少次正面
  22.                     if jz > jzpd:
  23.                         jzpd = jz #将连续出现正面次数的最高值赋予jzpd
  24.                 elif j == 2:
  25.                     jz = 0 #当出现正面时,将连续出现正面次数标记归0
  26.                     print("反面",end=" ")
  27.                     jf += 1 #计数连续出现反面次数
  28.                     js2 += 1 #统计一共出现多少次反面
  29.                     if jf > jfpd:
  30.                         jfpd = jf #将连续出现反面次数的最高值赋予jfpd
  31.                         w -= 1
  32.         else:
  33.             while w:
  34.                 j = random.randint(1,2)
  35.                 if j == 1:
  36.                     jf = 0 #当出现正面时,将连续出现反面次数标记归0
  37.                     jz += 1 #计数连续出现正面次数
  38.                     js1 += 1 #统计一共出现多少次正面
  39.                     if jz > jzpd:
  40.                         jzpd = jz #将连续出现正面次数的最高值赋予jzpd
  41.                 elif j == 2:
  42.                     jz = 0 #当出现正面时,将连续出现正面次数标记归0
  43.                     jf += 1 #计数连续出现反面次数
  44.                     js2 += 1 #统计一共出现多少次反面
  45.                     if jf > jfpd:
  46.                         jfpd = jf #将连续出现反面次数的最高值赋予jfpd
  47.                         w -= 1
  48.         print(f"总共模拟了{x}次抛硬币")
  49.         print("正面次数=",js1)
  50.         print("反面次数=",js2)
  51.         print(f"连续出现正面次数最多时为{jzpd}次")
  52.         print(f"连续出现正反面次数最多时为{jfpd}次")
  53.     except:
  54.         print(f"无法执行抛硬币{i}次") #显示错误消息(如抛硬币"print()"次)
  55. while True:
  56.     play()
  57.     x=input("还要玩吗?(输入“好的”继续,否则退出游戏)")
  58.     if x=="好的":
  59.         continue #继续
  60.     else:
  61.         break
  62. del x #清理内存
复制代码


程序优势:
1 使用try-except,避免报错;
2 使用局部变量,内存优化;
3 把play函数放入while循环,支持多次模拟.

满意的话,就给个 最佳答案

如有任何问题,请回复 666
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2025-4-10 13:51:53 | 显示全部楼层
爱编程的我 发表于 2025-4-8 11:42
修改后的代码如下:

你的代码跟我的差不多,2楼的就简洁很多
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-5 19:54

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表