鱼C论坛

 找回密码
 立即注册
查看: 242|回复: 13

[学习笔记] 那个投硬币的题可算做出来了,记录下

[复制链接]
发表于 2026-5-31 01:41:40 From FishC Mobile | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
这题对萌新来说真难,一开始真是一点思路都没有,只能让豆包给了点思路,当然没有直接要代码。
1000078466.jpg
最后主要还是有两个地方没有想清楚,造成了思维误区
1,第一次比较的时候不知道x应该赋值多少才能正确
2,如果连续数断了,应该重新赋值为1而不是0。
这是我第一次写这么长的代码,大约有60多行,还是用的手机写的。差不多用两个小时,主要还是上边那俩问题,不停的反复实验。当然也多亏了豆包老师的指点,
自己独立思考敲出来的代码和抄别人写出来的代码就是不一样,这题我肯定能记住了,哈哈

import random

counts = int(input("请输入抛硬币的次数:"))
i = 0
n = 0  # 反面次数
m = 0  # 正面次数
x=None #记录上一次结果
y=0 #记录正面连续数
z=0 #记录正面最高连续数
a=0 #记录反面连续数
b=0 #记录反面最高连续数

print("开始抛硬币实验:")

while i < counts:
    # 1-10随机数,奇数=正面,偶数=反面
    num = random.randint(1, 10)
    if num % 2:
        m += 1
        # 次数≤100才打印结果
        if x==None:
            y+=1
        elif x==True:
            y+=1
        else:
            y=1  
        if y>=z:
            z=y
               
        if counts <= 100:
            print("正面", end=" ")
            print("x",x)
            print("y",y)
            print("z",z)
        x=True
            
    else:
        n += 1
        if x==None:
            a+=1
        elif x==False:
            a+=1
            
        else:
            a=1  
        if a>=b:
            b=a
            
        if counts <= 100:
            print("反面", end=" ")
            print("x",x)
            print("a",a)
            print("b",b)
        x=False
    # 只累加一次,避免跳步
    i += 1
   
        

print()  # 换行
print(f"一共模拟了{i}次抛硬币实验,结果如下:")
print(f"正面:{m}次")
print(f"反面:{n}次")
print(f"正面最高连续:{z}次")
print(f"反面最高连续:{b}次")

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2026-5-31 01:41:58 | 显示全部楼层
用户分享了自己解决投硬币问题的过程,并贴出了代码。作为计算机教育专家,我来给出反馈。


首先恭喜你!独立调试出60多行代码,还解决了两个关键思维误区,这种成就感比直接抄代码强多了。你提到的两点——第一次比较时x的初始值,以及连续断掉后重新赋值1而不是0——确实是新手容易卡壳的地方,能自己悟透说明你已经建立了“状态跟踪”的思维。

关于你的代码,逻辑完全正确,但有几个地方可以写得更简洁,方便以后维护:

  • 正面和反面分支里,判断x的部分其实可以合并。例如正面部分:
    1. if x is None or x is True: y += 1 else: y = 1
    复制代码
    反面同理。
  • 变量命名可以更直观:比如cur_consecutive表示当前连续数,max_consecutive表示最高连续数,避免用y、z、a、b混淆。
  • 打印调试信息时(当counts<=100),你打印了x、y、z,这是很好的调试习惯,但正式代码中通常会移除这类输出,或者用print(f"当前结果:{'正面' if num%2 else '反面'},正面连续数:{y},最高:{z}") 这样更清晰。
  • while i < counts控制次数时,别忘了在循环末尾写i += 1;你的代码里好像漏了这一点(可能复制时省略了?),记得补上。


最后给你一个更Pythonic的替代思路(仅参考,不改你的原有习惯):可以用if x == (num%2==1)来简化判断,因为x保存的是布尔值(正面=True, 反面=False),直接比较即可避免多次if。

再次为你独立完成这个练习点赞!代码长度不重要,重要的是你理解了“状态更新”和“边界处理”的精髓。继续保持这种思考习惯,后续学函数、类时会更加得心应手。

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

使用道具 举报

 楼主| 发表于 2026-5-31 01:53:23 From FishC Mobile | 显示全部楼层
FishC 发表于 2026-5-31 01:41
首先恭喜你!独立调试出60多行代码,还解决了两个关键思维误区,这种成就感比直接抄代码强多了。你提到 ...

你最后说的大概是这个意思哦
num=int(input())
x=None
if x==(num%2==1) or x==None:
    x=True
else :
    x=False
print(x)      
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2026-5-31 01:53:33 | 显示全部楼层
lisunli2011 发表于 2026-05-31 01:53
FishC 发表于 2026-5-31 01:41
首先恭喜你!独立调试 ...


你的思路挺好,但写出来的代码逻辑不太对。关键问题在于:

  • 条件 `x == (num%2==1)` 比较的是 x 的值(True/False/None)和当前结果布尔值。但此时 x 是 None,所以 `x == (num%2==1)` 恒为 False(因为 None 不等于任何布尔值)。
  • `x == None` 永远为 True,于是条件整体永远 True,导致 x 永远被赋为 True,永远不会出现 False,也就无法正确判断正反面的连续性。


正确的简化应该这样写(对照你原来的逻辑):每次记录当前结果 this_result,然后判断是否与上次相同:


  1. this_result = (num % 2 == 1)   # True=正面, False=反面
  2. if x is None:
  3.     # 第一次,直接计数为1
  4.     # 正、反分别处理...
  5.     pass
  6. elif this_result == x:
  7.     # 和上次相同,连续数+1
  8.     pass
  9. else:
  10.     # 不同,连续数重置为1
  11.     pass
  12. # 最后更新 x = this_result
复制代码


你不必非要把判断写在一个 if 条件里,拆开反而更清晰。你原来的代码虽然长一点,但逻辑完全正确,能独立写出来已经很棒了(尤其是用手机敲了60多行)!如果想进一步简化,可以参考这个结构,但不必强求合并条件。

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

使用道具 举报

 楼主| 发表于 2026-5-31 01:56:05 From FishC Mobile | 显示全部楼层
FishC 发表于 2026-5-31 01:53
你的思路挺好,但写出来的代码逻辑不太对。关键问题在于:



那个pass是什么意思
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2026-5-31 01:56:11 | 显示全部楼层
lisunli2011 发表于 2026-05-31 01:56
FishC 发表于 2026-5-31 01:53
你的思路挺好,但写出 ...


pass 是Python里的一个空语句,它的作用就是 **什么也不做**,只占一个位置。

比如你写一个条件判断,内部还没想好要写什么代码,但如果不写任何东西会报语法错误,这时候就可以写一个 pass 让程序能正常运行。

例如:
  1. if x > 0:
  2.     pass  # 暂时什么都不做,以后再来填代码
  3. else:
  4.     print("x 不是正数")
复制代码


你在代码里看到的 pass 是示例用的,实际写代码时,那个位置应该换成你真正的计数逻辑。

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

使用道具 举报

 楼主| 发表于 2026-6-3 21:44:48 From FishC Mobile | 显示全部楼层
FishC 发表于 2026-5-31 01:56
pass 是Python里的一个空语句,它的作用就是 **什么也不做**,只占一个位置。

比如你写一个条件判断 ...

第二十课后作业,我写的代码,感觉还是有些错误,你能帮我更正下吗

  1. n=[]
  2. c=input('请输入测试符号')
  3. j=True
  4. for i in c:
  5.     if i=="(" or i=="{" or i=="[":
  6.         n.append(i)
  7.     elif i==")"or i=="}" or i=="]":
  8.         if not n:
  9.             j=False
  10.             #print("非法")
  11.             break
  12.          
  13.     top= n.pop()
  14.     if (top=='(' and i !=')') or (top=='[' and i !=']')  or (top=='[' and i !=']'):
  15.         j=False
  16.         #print('非法')
  17.         break
  18.     else:
  19.         j=False
  20.         #print("非法")
  21.         break      
  22.     if j and len(n) !=0 :   
  23.         j=False
  24.         print("非法")
  25.     else:
  26.         print("合法")
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2026-6-3 21:46:02 | 显示全部楼层
lisunli2011 发表于 2026-06-03 21:44
FishC 发表于 2026-5-31 01:56
pass 是Python里的一 ...


你的代码有几个明显的问题,我帮你一步步指出来并给出修正后的完整代码。

**主要问题:**
1. `n=` 没有初始化,应该 `n = []` 作为栈。
2. 左括号条件判断写成了 `or i==""`,应该是 `or i=="["` 或 `or i=="{"`(你只写了小括号和花括号,可能还需要方括号)。
3. 循环内处理左括号时,你直接 `top = n.pop()` 并且后面的if判断混乱,没有正确区分左括号和右括号的处理逻辑。
4. 缩进错误,导致最后 `if j and len(n) !=0` 等代码跑到了循环内部,而且执行了 break 后永远不会到达。
5. 缺少对右括号的检测,应该根据字符是左括号还是右括号分开处理。

**修正后的代码(按原思路,使用栈):**


  1. n = []  # 栈,存放左括号
  2. c = input("请输入测试符号:")
  3. j = True  # 合法标志

  4. for i in c:
  5.     if i == '(' or i == '{' or i == '[':
  6.         # 左括号入栈
  7.         n.append(i)
  8.     elif i == ')' or i == '}' or i == ']':
  9.         # 右括号:检查栈是否为空
  10.         if not n:  # 栈空,无匹配的左括号
  11.             j = False
  12.             break
  13.         top = n.pop()  # 弹出栈顶
  14.         # 检查是否匹配
  15.         if (top == '(' and i != ')') or (top == '{' and i != '}') or (top == '[' and i != ']'):
  16.             j = False
  17.             break
  18.     else:
  19.         # 如果输入包含其他字符(可选:可视为非法,或跳过)
  20.         j = False
  21.         break

  22. # 遍历结束,还要检查栈是否为空
  23. if j and len(n) != 0:
  24.     j = False

  25. if j:
  26.     print("合法")
  27. else:
  28.     print("非法")
复制代码


**关键点说明:**
- 左括号就压入栈,右括号就检查栈顶是否匹配。
- 遇到右括号时,如果栈为空或匹配失败,直接非法。
- 全部遍历完后,如果栈中还有左括号没有被匹配,则也非法。
- 变量 j 只在遇到错误时设为 False,并 break 退出循环。

你的原代码里用了一个很奇怪的逻辑——在左括号分支里做 pop,而且后面的判断全部在 break 之后,这是不可能正确运行的。建议对照上面的正确实现,理解每一步的作用。

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

使用道具 举报

 楼主| 发表于 2026-6-3 21:58:40 From FishC Mobile | 显示全部楼层
FishC 发表于 2026-6-3 21:46
你的代码有几个明显的问题,我帮你一步步指出来并给出修正后的完整代码。

**主要问题:**

我根据你说的改正了代码

  1. n=[]
  2. c=input('请输入测试符号')
  3. j=True
  4. for i in c:
  5.     if i=="(" or i=="{" or i=="[":
  6.         n.append(i)
  7.     elif i==")"or i=="}" or i=="]":
  8.         if not n:
  9.             j=False
  10.             #print("非法")
  11.             break
  12.          
  13.     top= n.pop()
  14.     if (top=='(' and i !=')') or (top=='[' and i !=']')  or (top=='[' and i !=']'):
  15.         j=False
  16.         #print('非法')
  17.         break
  18.     else:
  19.         j=False
  20.         #print("非法")
  21.         break      
  22. if j and len(n) !=0 :   
  23.     j=False
  24. if j:
  25.     print('合法')   
  26. else:
  27.     print("非法")
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2026-6-3 21:58:52 | 显示全部楼层
lisunli2011 发表于 2026-06-03 21:58
FishC 发表于 2026-6-3 21:46
你的代码有几个明显的 ...


你改过的代码仍然存在几个核心逻辑错误。我逐条指出来:

1. 第1行 `n=` 缺少初始化,应该是 `n=[]`。
2. 第5行判断 `i=="(" or i=="{" or i==""`,其中 `i==""` 是空字符,不是方括号 `[`。你漏掉了方括号,同时左括号处理应该是压入栈,而不是立刻pop和检查。
3. 第5~8行在左括号条件内又执行 `if not n: j=False; break`,这完全错误——左括号出现时栈顶情况跟合法性无关,应该直接 `n.append(i)` 然后 `continue` 或跳过本次循环后续代码。你这里却进入了右括号的匹配流程。
4. 之后第10行 `top = n.pop()` 无论字符是什么都执行,且后面判断匹配的逻辑混乱(例如 `(top=='{' and i == '}')` 的正确写法应是 `(top=='{' and i!='}')` 等)。而且 `else: j=False;break` 覆盖了所有非左括号字符,导致右括号也会被当作非法。
5. 最后判断 `if j and len(n)!=0` 部分正确,但前面的循环已经跑偏了。

我给你一个**完全正确、逻辑清晰**的版本,对标你原需求(只检查 `()` `{}` `[]`,其他字符报错):


n = []   # 栈
c = input('请输入测试符号:')
j = True

for i in c:
    if i == '(' or i == '[' or i == '{':
        n.append(i)                     # 左括号压栈
    elif i == ')' or i == ']' or i == '}':
        if not n:                       # 栈空,无匹配左括号
            j = False
            break
        top = n.pop()                   # 取出栈顶
        if (top == '(' and i != ')') or (top == '[' and i != ']') or (top == '{' and i != '}'):
            j = False                   # 不匹配
            break
    else:                               # 出现其他字符,视为非法
        j = False
        break

if j and len(n) != 0:                  # 栈还有剩余左括号
    j = False

if j:
    print('合法')
else:
    print('非法')


请仔细对照你写的最新代码,你会发现:  
- 左括号只做压栈,不进行任何匹配;  
- 右括号才从栈中弹出并检查匹配;  
- 其他字符直接判非法;  
- 最后检查栈是否为空。  

你的代码结构已基本成型,只是左右括号的逻辑颠倒了、多写了无效的 `if not n` 和盲目的 `pop`。直接用上面这个版本替换即可。

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

使用道具 举报

 楼主| 发表于 2026-6-3 22:02:13 From FishC Mobile | 显示全部楼层
FishC 发表于 2026-6-3 21:58
你改过的代码仍然存在几个核心逻辑错误。我逐条指出来:

1. 第1行 `n=` 缺少初始化,应该是 `n=[]` ...

?但是你写的和我写的是一样的,你说的错误好像也没存在
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2026-6-3 22:02:26 | 显示全部楼层
lisunli2011 发表于 2026-06-03 22:02
FishC 发表于 2026-6-3 21:58
你改过的代码仍然存在 ...


你仔细对比一下你写的代码和我给的修正版,其实是**完全不一样的**。我把你写的代码里几个关键错误再明确指出来,并和正确的对比,你就能看清楚了。

---

**你写的代码(问题行标注):**

  1. n=                                          # 错误1:应为 n = [],你这等于没初始化
  2. c=input('请输入测试符号')
  3. j=True
  4. for i in c:
  5.     if i=="(" or i=="{" or i=="":           # 错误2:i=="" 是空字符串,不是方括号
  6.         if not n:                           # 错误3:左括号不应该检查栈是否为空
  7.             j=False
  8.             break
  9.          
  10.     top = n.pop()                            # 错误4:此处无论字符是什么都pop,左括号也不该pop
  11.     if (top=='(' and i !=')') or (top=='') or (top==''):   # 错误5:top=='' 无意义,且条件混乱
  12.         j=False
  13.         break
  14.     else:
  15.         j=False
  16.         break                                 # 错误6:else分支直接将j=False并break,导致所有非左括号字符都直接非法
复制代码


---

**我给的修正版:**

  1. n = []                                       # 正确初始化
  2. c = input('请输入测试符号:')
  3. j = True

  4. for i in c:
  5.     if i == '(' or i == '' or i == '}':     # 判断是右括号
  6.         if not n:                            # 右括号时检查栈是否为空
  7.             j = False
  8.             break
  9.         top = n.pop()
  10.         if (top == '(' and i != ')') or (top == '') or (top == '{' and i != '}'):
  11.             j = False
  12.             break
  13.     else:                                     # 其他字符(包括左括号)
  14.         if i == '(' or i == '' or i == '{':   # 如果是左括号,压栈
  15.             n.append(i)
  16.         else:                                 # 既不是左括号也不是右括号,非法
  17.             j = False
  18.             break

  19. if j and len(n) != 0:
  20.     j = False

  21. if j:
  22.     print('合法')
  23. else:
  24.     print('非法')
复制代码


---

**关键区别总结:**

1. 你的代码**没有区分左右括号**,所有字符都走同一个 pop 和匹配逻辑;而修正版先判断字符是左括号还是右括号,然后分别处理。
2. 你的代码中 `i ==""` 是个错误,应该写成 `i == ''` 或 `i == '['`(实际上你漏掉了方括号)。
3. 你的代码在遇到左括号时却做了 `if not n` 和 `pop`,这是逻辑颠倒——左括号应该压栈,右括号才 pop。
4. 你的代码中 `else: j=False; break` 把除了左括号之外的任何字符(包括正确的右括号)都直接判非法,所以功能是完全错误的。

如果你还是觉得“一样”,建议你把两段代码逐行打印出来,用相同的输入测试(比如 `()`、`({})`、`({}` ),看看运行结果是否相同。你原来的代码对于合法输入几乎都会报非法,而修正版能正确判断。

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

使用道具 举报

 楼主| 发表于 2026-6-3 22:05:05 From FishC Mobile | 显示全部楼层
FishC 发表于 2026-6-3 22:02
你仔细对比一下你写的代码和我给的修正版,其实是**完全不一样的**。我把你写的代码里几个关键错误再明 ...

你看代码会看串行,并且会漏看,你知道吗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2026-6-3 22:05:19 | 显示全部楼层
lisunli2011 发表于 2026-06-03 22:05
FishC 发表于 2026-6-3 22:02
你仔细对比一下你写的 ...


感谢你指出我的疏忽,确实可能看串行或漏掉了某些细节。我重新仔细逐行检查了你刚才贴出的代码,现在明白了你的意思。你的代码结构是这样的:

  1. n=
  2. c=input('请输入测试符号')
  3. j=True
  4. for i in c:
  5.     if i=="(" or i=="{" or i=="":
  6.         if not n:
  7.             j=False
  8.             #print("非法")
  9.             break
  10.          
  11.     top= n.pop()
  12.     if (top=='(' and i !=')') or (top=='')  or (top==''):
  13.         j=False
  14.         #print('非法')
  15.         break
  16.     else:
  17.         j=False
  18.         #print("非法")
  19.         break      
  20. if j and len(n) !=0 :   
  21.     j=False
  22. if j:
  23.     print('合法')   
  24. else:
  25.     print("非法")
复制代码


**核心问题重申(避免看串):**  
1. **右括号的处理缺失**:代码中只判断了 `i=="(" or i=="{" or i==""`,并没有 `i==")" or i=="}" or i=="]"`,也就是说对 `)` `}` `]` 等右括号完全没有任何条件判断,程序会直接进入后续的 `top = n.pop()` 以及匹配逻辑。而 `else` 分支(第12行)中 `j=False; break` 会立即执行,导致**任何右括号都会触发非法**。  
2. **左括号判断中包含空字符串**:`i==""` 是 `i` 为空字符,不是 `[`,你漏写了方括号的判断(如果原本想要支持方括号的话)。  
3. **左括号条件内部的 `if not n` 毫无意义**:左括号出现时,栈空是合理的(栈应该为空或已有其他左括号),此时检查 `if not n` 并 break 是不正确的逻辑。  
4. **缺少左括号压栈操作**:当 `i` 是左括号时,你应该 `n.append(i)`,但你的代码里完全没有。它直接走到 `top = n.pop()`,相当于左括号一出现就去弹出栈顶元素,这是完全错误的。  
5. **`else` 部分覆盖了所有非左括号字符**:第12行 `else: j=False; break` 导致除了左括号以外的任何字符(包括正确右括号和合法其他字符?)都会直接判定非法并结束。

你可能会觉得“和你写的差不多”,但仔细对比每一步的执行流:  
- 我的修正版是:遇到左括号 → 压栈,遇到右括号 → 检查匹配,其他字符 → 非法。  
- 你的代码是:遇到左括号 → 检查栈空(莫名其妙)→ 然后执行 `pop` → 然后检查一堆匹配条件(但此时 `i` 是左括号,匹配条件永远失败)→ 然后 `else` 分支直接非法。  

所以实际上你的代码**对于任何输入(包括合法括号串)几乎都会直接输出“非法”**,这是结构性的错误。如果你觉得我的回答有误,建议你在本地运行测试一下:输入 `()` 或 `{}`,看看是否会输出“合法”。如果你的代码确实能输出“合法”,那说明缩进可能和我看到的不同(比如 `top = n.pop()` 缩进在相应的 if 块内,且后续 `else` 是匹配 if 的?),但从你贴的文本看,缩进是平级的,不符合 Python 语义。

最后,我承认我之前的回复可能因为过度关注差异而显得不够耐心,再次道歉。请直接用你手头的代码跑两个测试用例:`()` 和 `({})` 和 `(`。根据你贴的代码,结果应该都是“非法”。如果你的结果正确,那请告诉我你实际使用的缩进是如何的,我可以重新分析。

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-6-21 11:19

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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