farm2046 发表于 2025-4-7 12:21:52

请问怎么优化统计抛硬币正反面代码

做了课后练习题抛硬币统计,下面这个代码是我自己写的,请问能怎么优化,最好是能指出我的代码繁冗在哪里,谢谢!
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}次")

jackz007 发表于 2025-4-7 12:21:53

本帖最后由 jackz007 于 2025-4-9 12:46 编辑

import random
n = int(input("请输入抛硬币次数:"))
k , jz , jf , jzpd , jfpd = 0 , 0 , 0 , 0 , 0
for _ in range(n) :
    if random . randint(1 , 2) % 2 :               # 如果是正面
      k += 1                                     # k - 正面总计数
      if jf : jf = 0                           # 连续反面计数清零
      jz += 1                                    # 连续正面计数增 1
      if jz > jzpd : jzpd = jz                   # 如果连续正面计数超过记录,则更新记录
      s = '【正面】'
    else :
      if jz : jz = 0                           # 连续正面计数清零
      jf += 1                                    # 连续反面计数增 1
      if jf > jfpd : jfpd = jf                   # 如果连续反面计数超过记录,则更新记录
      s = '[反面]'
    if n < 100 : print(s)                        # 如果抛币次数在 100 次以内,则打印每一次的抛币结果
print('总共抛币【{}】次,其中:正面【{}】 次,反面 [{}] 次,最大连续正面【{}】次,最大连续反面 [{}] 次。' . format(n , k , n - k , jzpd , jfpd))

FishC 发表于 2025-4-7 12:23:01


import random

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

# 初始化计数器
heads = tails = 0
current_heads = current_tails = 0
max_heads = max_tails = 0

for _ in range(total):
    coin = random.choice(["正面", "反面"])# 更直观的随机选择
   
    if coin == "正面":
      heads += 1
      current_heads += 1
      current_tails = 0# 重置反面连续计数
      if current_heads > max_heads:
            max_heads = current_heads
    else:
      tails += 1
      current_tails += 1
      current_heads = 0# 重置正面连续计数
      if current_tails > max_tails:
            max_tails = current_tails
   
    if print_result:
      print(coin, end=" ")

print(f"\n总共模拟了{total}次抛硬币")
print(f"正面次数: {heads}")
print(f"反面次数: {tails}")
print(f"连续出现正面次数最多时为{max_heads}次")
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 小助理,如未能正确解答您的问题,请继续追问。

爱编程的我 发表于 2025-4-8 11:42:50

修改后的代码如下:

import random
def play:
    i=input("请输入抛硬币次数:")
    try:
      w=int(i) #检测是否为整数
      if "." in i: #如果是浮点数
            a="FishC"+520 #强行报错,跳出try代码块   
      jz=0 #统计连续出现正面次数的标记
      jzpd=0 #连续出现正面计数次数最多统计
      jf=0 #统计连续出现反面次数的标记
      jfpd=0 #连续出现反面计数次数最多统计
      js1=0 #硬币正面出现次数计数
      js2=0 #硬币反面出现次数计数
      if w < 100:
            while w:
                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
                        w -= 1
      else:
            while w:
                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
                        w -= 1
      print(f"总共模拟了{x}次抛硬币")
      print("正面次数=",js1)
      print("反面次数=",js2)
      print(f"连续出现正面次数最多时为{jzpd}次")
      print(f"连续出现正反面次数最多时为{jfpd}次")
    except:
      print(f"无法执行抛硬币{i}次") #显示错误消息(如抛硬币"print()"次)
while True:
    play()
    x=input("还要玩吗?(输入“好的”继续,否则退出游戏)")
    if x=="好的":
      continue #继续
    else:
      break
del x #清理内存


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

满意的话,就给个 最佳答案 吧 {:10_264:}

如有任何问题,请回复 666

farm2046 发表于 2025-4-10 13:51:53

爱编程的我 发表于 2025-4-8 11:42
修改后的代码如下:




你的代码跟我的差不多,2楼的就简洁很多
页: [1]
查看完整版本: 请问怎么优化统计抛硬币正反面代码