鱼C论坛

 找回密码
 立即注册
查看: 5695|回复: 26

[学习笔记] 【Pyhon 009讲心得体会】【摸球和水仙花数 】

[复制链接]
发表于 2018-11-16 15:10:54 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 heidern0612 于 2019-7-28 10:59 编辑

写的内容都是自我思考的过程,难免有疏漏,有错误的地方欢迎广大鱼油给予指正!

学到这一课,眼前一黑,wakao,这么难,有木有?


1、学到了for循环:for i in range(0,10,2)

0到10是循环的范围,不包括10,所以其实是0到9循环的范围。

2表示的是步进,表示隔一个一计算。就像上楼梯,10层的楼梯,如果你两个两个(步进2)的上,五次就上完了。



2、break 和continue

break是跳出整个的大循环,而continue跳出的是当次循环剩余的语句,不影响后面的继续循环。

所以continue我理解为更像是一个过滤器,类比filter,他把不能执行的东西continue了,把能执行的东西留了下来。

例:
  1. #coding=gbk
  2. var = "Apython"
  3. for i in var:
  4.         if i == "A" :
  5.                 continue
  6.         else:
  7.                 print(i,end = "")
复制代码


输出的结果是python,把"A"过滤掉了,好神奇,有木有?

break和continue相同点都在于不执行下面的语句,区别是break就像是癌症,坏了就没办法循环再开始,而continue就像小感冒类似,当前坏了还可以再从头循环。



3、密码验证问题:

        1、小甲鱼老师小立了一个flag,用来判断密码输入次数;

        2、in 成员操作符,用于关键字判断'*'是否在密码内,是的话,continue过滤掉,跳回循环开始输入密码阶段;

        3、密码输入正确,程序break跳出。
       
此题主要就是考察in成员操作符和continue的作用,很多同学学了却始终没用过continue或in成员操作符(例如我),不是不懂,而是不知道该什么时候用,想办法跟游戏关联一下,你就会发现很多用途咯。




4、摸球的问题:(此球非彼球……)

卧槽,看着好复杂有木有?一点也不明白有木有?谁第一眼看着这种for循环套for循环的语句都懵逼。

其实按照正常人思维推导一下,感觉似乎没有想象的那么难。

只是简单的嵌套三层的for循环,一起分析一下:




首先是red的for循环:

红球数量是0的时候,有几种组合呢?

红球*0 + 黄球*2 + 绿球*6

红球*0 + 黄球*3 + 绿球*5

红球为零的情况下,为了达到摸出的球有8只,只有这两种组合。


红球数量为1的时候呢?

红球*1 + 黄球*1 + 绿球*6

红球*1 + 黄球*2 + 绿球*5

红球*1 + 黄球*3 + 绿球*4


可以从上面看出来,在红球是1的时候,黄球就已经几乎循环了一个遍了,继续:


红球*2 +黄球*0 + 绿球*6

红球*2 + 黄球*1 + 绿球*5

红球*2 + 黄球*2 + 绿球*4

红球*2 + 黄球*3 + 绿球*3


可以看出,红球是2的时候,为了达到8个球的总数,黄球已经可以为零了,话说就是摸出两个红球的时候,黄球就已经从0到3遍历了一遍了。继续:

红球*3 + 黄球*0 + 绿球*5

红球*3 + 黄球*1 + 绿球*4

红球*3 + 黄球*2 + 绿球*3

红球*3 + 黄球*3 +绿球*2


至此,红球和黄球都完成了自身的遍历。红球和黄球的方式推完了,下面我们算绿球的:

绿球为零的时候,红球和黄球都算上(红球、黄球都各只有三个),为了摸出8个球,不够,差俩。

绿球为一的时候,红球和黄球都算上,不够,差一个。

绿球为二的时候呢?,好熟悉,不就是推导黄球遍历的时候 红球*3 + 黄球*3 + 绿球*2 的时候嘛!

绿球为三呢?也找到了,绿球一直到为六(只有六个),也都在上面找到了。

所以,算一算方法,一共是13种,是不是跟答案一样呢?


实际上我不推荐这种笨方法,但是这种笨方法对理解此题有效果。

可以从推算中看出,实际上我们先遍历了红球的从零到3的变化,也就是for i in range(0,4)

其次,红球遍历完了,我们遍历的是黄球(0,4),然后是绿球(2,7)。

所以大循环上,先套上red,red循环0的时候,下面yellow循环2,再下面绿的循环6.

后套上yellow,再套上green.(I don't have any green...)

就把这个题理解了。


5、水仙花数

为啥最后说捏?因为我当时理解这个很费劲。。虽然自己用别的方法做出来了,但是感觉没老师那么精简,另外这个或许也是这节课程里面最难的,分析不易。

先贴上我自己的做法

  1. for i in range(1,10):
  2.     for j in range(0,10):
  3.         for k in range(0,10):
  4.            if i*100+j*10+k==i*i*i+j*j*j+k*k*k:
  5.                 print(i*100+j*10+k)
复制代码



类似还有以下这种:

  1. for i in range(100,999):
  2.     a=i//100
  3.     b=(i%100)//10
  4.     c=i%10
  5.     if i==a**3+b**3+c**3:
  6.         print(i)
复制代码



小甲鱼老师的办法现在我用带入法仔细分析下:
  1. for i in range(100, 1000):
  2.     sum = 0
  3.     temp = i
  4.     while temp:
  5.         sum = sum + (temp%10) ** 3
  6.         temp //= 10         # 注意这里要使用地板除哦~
  7.     if sum == i:
  8.         print(i)
复制代码


首先第一行,for i in range(100,1000)这个基本都比较好理解吧?

0 赋值给sum,(sum后面其实就是水仙花三者平方相加的和;);temp = i ,也就是for 循环后100到999所有的值

while这里:


第一次循环:
我们首先拿153测试下,当 i循环到153时,temp 也是153.

sum = 0+(153%10)**3;  153%10余数是3,也就是3的3次方,结果是27,也就是此时的sum = 27;

temp // 10 = 153//10 = 15 ; 地板除,不要余,其实就相等150 /10 的结果。

此时temp == 15,不满足temp == 0时while跳出循环,所以循环继续;


第二次循环:
sum = 27(上个sum的值) +(15%10)**3 ;  15%10的余数是5,也就是5的3次方,结果是125;此时sum = 125 +27 =152;

temp //10 , 也就是15//10;地板除,不要余数;相等于10//10 = 1

此时temp == 1,不满足temp ==0时while跳出循环,循环继续。


第三次循环:
sum = 152(上个sum的值) +(1%10)**3 ;  1%10的余数是1,也就是1的3次方,结果是1;此时sum = 152+1 = 153;

temp //10 , 也就是1//10;地板除,不要余数; 数值为0。

此时temp == 0,满足temp ==0时while跳出循环,循环中断。


此时判断if语句,如果sum和值相等,就打印i。此时sum=153, temp在未开始循环时也是153,i的值一开始我们测试的就是153.所以两者相等,打印出来。



这种简单的利用地板除和求余除的办法我脑子愚笨,没想出来,只有大神才用这种简单的办法,我用上面那两种方法就挺好,不过能近距离接触大神的用法,分析下也挺好的。



简单用370再验证一下:

1、370%10 余0 ,sum = 0, temp =370//10 = 37 ;
2、37%10 余7,sum =0+ 7**3 =343, temp = 37//10 = 3
3、3%10 余3, sum =  343+ 3**3 = 370, temp = 3//10 = 0

temp为False(即temp为0)跳出循环。

sum = i =370,所以370也是个水仙花数。


至于为什么 1%10余1,或1//10余0,请自行百度或者拿壳自己做下记住就可以了。

print(1//10)

print(1%10)


评分

参与人数 2荣誉 +6 鱼币 +5 贡献 +3 收起 理由
你知道吗我会 + 1 感谢楼主无私奉献!
编程小白li + 5 + 5 + 3 感谢楼主无私奉献!

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-12-12 15:36:08 | 显示全部楼层
数学实在太差了,看的还是云里雾里
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-13 16:56:57 | 显示全部楼层
temp123为例开始;sum为零,然后第一次运行

sum=sum+-----temp为123%余数相当于3**3
temp=地板除那行变成12
返回sum行,3**3加2**3
再回到地板除变成1
再返回sum 结果就是3**3+2**3+1**3

然后返回temp=each,数字增大一个序数直至153

运行的结果其实就是3**3+5**3+1**3

然后进入打印第一次,然后再返回到temp=each--------------

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2019-2-1 18:05:10 | 显示全部楼层
摸球的问题一直没看懂,结果看下你的解题思路,哇靠,原来这么简单的啊~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-2-15 11:26:03 | 显示全部楼层
做练习时也感受到了这章的难度:
1. 密码验证程序,没意识到 in 是个操作符可以灵活运用,以为只能搭配for使用,走了弯路
2. 水仙花数写得和楼主第二个程序一样,范例代码中也没意识到temp//= 10以后不为零继续循环,所以完全没看懂整个程序
3. 三色球自己还往排列组合上去想,审题不清?绿球是range(2,7)也是自己要绕一圈才能想明白的点
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-2-16 09:03:30 | 显示全部楼层
可以说是很详细的解析了,
虽然办法笨, 一步一步分析, 一步一步验证,但是真的很管用
谢谢楼主大大
也谢谢楼主大大回复解答我的求助帖
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-13 10:12:55 | 显示全部楼层
Judie 发表于 2019-2-16 09:03
可以说是很详细的解析了,
虽然办法笨, 一步一步分析, 一步一步验证,但是真的很管用
谢谢楼主大大

表示 虽然能看懂解析,但是小甲鱼的方法我还是用不出来啊/捂脸
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-14 17:03:17 | 显示全部楼层
感谢分享!之前这里也卡住了半天
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-29 20:12:43 | 显示全部楼层
感谢分享!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-29 22:41:24 | 显示全部楼层
感谢分享
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-15 10:54:28 | 显示全部楼层
想问一下为什么要把 i 的值赋给 temp 变量, 不能直接用 i 进行运算吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-19 14:42:14 | 显示全部楼层
小甲鱼老师为什么这么大神
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-20 19:00:07 | 显示全部楼层
哪里设定有temp ==0时while跳出循环,循环中断啊?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-23 03:30:42 | 显示全部楼层
Judie 发表于 2019-2-16 09:03
可以说是很详细的解析了,
虽然办法笨, 一步一步分析, 一步一步验证,但是真的很管用
谢谢楼主大大

这里看到大佬了哈哈哈哈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-23 10:03:20 | 显示全部楼层
西瓜板栗 发表于 2020-3-22 14:30
这里看到大佬了哈哈哈哈

哈哈哈哈哈 你好啊呀~
你可以去看看我的学习笔记呀!

这是淘帖

朱迪的Python学习笔记
https://fishc.com.cn/forum.php?m ... =view&ctid=1618
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-26 11:35:59 | 显示全部楼层
看大神笔记一下子就理解了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-26 18:52:47 | 显示全部楼层
作为真·零基础学员,正打算上来问这节课的作业的时候就看到课代表heidern0612的答疑,真的超感动耶!
摸球问题课代表说得非常详细,本零很容易就理解了;但水仙花数那道题,本零看课代表的笔记还是有些吃力。
我水仙花数那道题就是用的100*a + 10*b + c的笨办法。

小甲鱼老师的答案对我来说其实有3个难点:
第一个是不知道temp //= 10的含义。对,我零基础到完全不知道有这个用法,并且没跟+= 1或-= 1联系起来。
第二个是while temp有个隐藏含义,就是temp == 0时,while循环会停止。因为while 0和while False是一个效果,这个小甲鱼老师其实讲过,我给忘了。
第三个就是sum的意思。经课代表分析,才明白sum就是“个”“十”“百”这三位上的3个数字的立方和。

可是第三个问题实在是知其然不知其所以然。为什么用sum可以表示3个数字的立方和?前面的i = 100到152的时候,sum到底发生了什么?

对于这个问题,大佬们可能不屑于了解,反正for循环每轮开头sum就归零了管那么多干啥。
但是对于本零基础学员来说,这么流弊的写法的诞生过程太令人好奇了。
于是本零就决定,吸取三色球的穷举精神,从故事的源头开始探究……

for循环的第一轮循环开始,i = 100,sum = 0,temp = 100:
①sum = sum + (100%10) ** 3,所以新sum == 0,新temp == 10,即temp != 0,因此while循环继续(值得注意的是,外层的for循环仍在第一轮,此时i仍然是100);
②sum = sum + (10%10) ** 3,所以新新sum依然== 0,新新temp == 1,仍!= 0,因此while循环继续(此时i仍然是100);
③sum = sum + (1%10) ** 3,1%10 == 1(1除以10商0余1这个大家应该都知道),最新sum == 1啦,最新temp由于1//10 == 0(地板除法嘛,0.1向下取整可不就是0),while循环就此结束。
所以这个时候,i = 100的情况就讨论完了。

for循环的第一轮循环也告一段落,现在开始第二轮咯,i = 101,sum = 0,temp = 101:
①sum = sum + (101%10) ** 3,所以新sum == 1,新temp == 10,即temp != 0,因此while循环继续;
②sum = sum + (10%10) ** 3,所以新新sum依然== 1,新新temp == 1,仍有!= 0,因此while循环继续;
③sum = sum + (1%10) ** 3,最新sum == 2,最新temp == 0,while循环就此结束。
i = 101的情况就讨论完了。

这两轮for循环考察完,我们应该就能比较容易理解sum为什么是三个数字的立方和了:
①i是三位数,每轮for循环的temp都是取的i的值,因此每轮for循环最开始的temp也都是三位数;
②每轮for循环下的while循环都不止一次;
③第一轮while循环得到得到的新sum,其实是三位数temp的个位数的立方,毕竟新temp(即temp%10)就是取原temp这个三位数除以10的余数嘛,三位数除以10,余数当然就是这个三位数的个位数啦;
④第一轮while循环最后对原temp做的地板除法,其实是在个位数确定之后,为了刨除个位数的影响,在下一轮循环中进一步对原temp的十位数做讨论进行的准备(这句话不好理解,可以直接跳到下一条);
⑤这个地板除法得到的新temp就是取原temp的百位数和十位数组成的两位数,即原temp的百位数变成了新temp的十位数,原temp的十位数则变成了新temp的个位数,所以第二轮while循环中(新temp%10)是取新temp这个两位数除以10的余数,得到的余数是新temp的个位数,也就是原temp的十位数了;
⑥因此,第二轮while循环中得到的新新sum,则是第一轮得到的新sum(原temp个位数的立方)与原temp的十位数的立方的和;
⑦同理,第三轮while循环中得到的最新sum,就是新sum+新新sum+原temp的百位数的立方== temp的个位数、十位数、百位数的立方和;
⑧while循环到第三轮的时候,到temp //= 10这一步,都会成为原temp的百位数对10做地板除法,百位数是1到9的数字,对10做地板除法必然为0,意思就是while循环到第三轮的时候一定会结束,不会有第四轮;
⑨至此,我们明白每轮for循环下面的while循环一定且仅会循环三轮,这三轮的成果就是第三轮得到的最新的sum值,它是原temp的百位数、十位数、个位数的立方和;
⑩原temp是不是水仙花数,就是靠小甲鱼老师代码的第7、8行判断的,是水仙花数,那依照概念,原temp(也就是本轮for循环的i)的百位数、十位数、个位数的立方和与原temp自身相等,也就应该有最新sum==原temp==i,满足这个条件,i就被打印出来;不满足,本轮for循环的i就不是水仙花数,就应该开始下一轮for循环,根据range序列开始对新的i进行判断。遍历(本零其实不知道“遍历”能不能这么用哈)完了range里的所有i,所有的水仙花数就被找出来了。

以上就是本零总结的学渣笔记,啊写的时候觉得很清楚,怎么写完了自己读一遍还是觉得好难懂QAQ
唉不管了,希望能给其他学渣带来帮助吧,大佬们请一笑而过啦~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 3 反对 0

使用道具 举报

发表于 2020-5-23 17:42:25 | 显示全部楼层
谢谢,因为你提供了其他的思路可以解决这个问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-26 10:28:33 | 显示全部楼层
楼主可以的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-26 23:57:24 | 显示全部楼层
本帖最后由 老西医学煸橙 于 2020-5-27 00:04 编辑

不看老哥的笔记,我还在水仙花里卡着,现在懂了,非常感谢!
还有中间回帖的“dgfzyr”兄,也把甲鱼佬的代码与数学算式的联系清楚写出了,感谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-20 04:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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