鱼C论坛

 找回密码
 立即注册
查看: 7136|回复: 23

[技术交流] Python:问题贴之水仙花数

[复制链接]
发表于 2017-8-6 21:27:45 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 新手·ing 于 2018-3-25 11:30 编辑

水仙花数问题:

看不懂循环中的内容,求大神讲解


正确代码:
  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)
复制代码


选材来自帖子:http://bbs.fishc.com/thread-73981-1-1.html

Sixpy大神的中文赋值法:
  1. for 数 in range(100, 1000):
  2.     立方和 = 0
  3.     商 = 数
  4.     while 商:
  5.         商,余 = divmod(商,10)
  6.         立方和 += 余**3
  7.         
  8.     if 立方和 == 数:
  9.         print(数)
复制代码



gcorgc123的栗子:
首先,用temp%10,这里是“取个位数的意思”!然后在循环中,while temp循环中,每进行一次循环,temp会去掉各位数,即temp//=10.最后一点是,while temp的循环条件,最终temp会等于0,从而结束循环。相信明白这几点应该理解没问题了。举个栗子
  1. i=153
  2. temp赋值,为153,
  3. while 153#153为真,循环继续
  4. temp%10等于3,其三次方的值加在sum中
  5. temp//=10,temp变成15
  6. 判断,while 15#15为真,循环继续
  7. 依次类推。
复制代码



                               
登录/注册后可看大图


在这里 while 循环是以 temp 变量不为零为基础的(初始值是 100,下面以153为例):
1、进入循环,temp与10取余等于3(其实就是得到了153的个位数的值);
2、然后将得到的值进行立方运算 ,并且将值存储到 sum 变量中去,这时sum等于27;
3、然后将 temp 的值与 10 进行地板除法,等于15(这一步就把153转换成了两位数,也就是去除了个位数)
4、然后再次进入while循环(因为 temp 这时等于15 ,不为零);
5、temp 与 10 取余等于 5 将其立方累加到 sum 变量中去,这时sum 等于 (27 + 125);
6、temp 与 10 进行地板除法得到 1 (这一步把15转换成了一位数,去除了十位数)
7、再次进入while循环(temp等于1不为零)
8、temp与10取余等于1,立方运算后累加到sum,这时sum等于(27 + 125 + 1)
9、temp 与 10 进行地板除法等于 0;
10、退出while循环。
11、这时 sum 等于 153(符合条件被打印出来)

是不是豁然开朗,水仙花数就是这么简单
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-8-19 20:33:57 | 显示全部楼层
这就是传说中的中文编程
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-27 14:48:25 | 显示全部楼层
   while temp:
        sum = sum + (temp%10) ** 3
        temp //= 10         # 注意这里要使用地板除哦~

不好理解的是这个地方,当初我也想了老半天,差点崩溃了。
假设temp = 153,下面的循环就是这样
sum = 3 ** 3    #先用取余数把个位数取出来求立方
temp = 15    #用地板擦除把153变成15

接下来循环一次
sum = sum + 5 **3   #这时是把十位数取出来,加上上面个位数的立方
temp = 1     #用地板擦除把15变成1

接下来最后一个循环
sum = sum + 1 ** 3   #这是把百位数取出来求立方,加上上面
temp = 0    #用地板擦除把1变成0

这个程序的想法就是把个位数取出来求立方,再十位数取出来求立方加上前面,最后把百位数取出来求立方加上前面,即153 = 3^3 + 5^3 +1^3。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-3 00:30:14 From FishC Mobile | 显示全部楼层
小甲鱼的 if sum == I 为什么要缩进 为什么缩进和不缩进答案不一样呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-11-10 22:06:08 | 显示全部楼层
本帖最后由 还是鱼头好 于 2018-7-3 20:45 编辑

马住,周末继续看……

结合第18讲,第9讲的水仙花数的求法终于看懂了T____T
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-11-20 20:44:54 | 显示全部楼层
Sherman 发表于 2017-8-27 14:48
while temp:
        sum = sum + (temp%10) ** 3
        temp //= 10         # 注意这里要使用地板 ...

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

使用道具 举报

发表于 2018-6-27 08:03:39 | 显示全部楼层
学什么都是中文才能看得懂
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-20 22:24:12 | 显示全部楼层
变态的算法....
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-4 13:47:38 | 显示全部楼层
for number in range (100,1000):
    unit = number%100%10   #获得个位数
    ten  = int (number%100/10)  #获得十位数
    hunder = int (number/100)   #获得百位数
    if unit**3 + ten**3 + hunder**3 == number:  #检验是否为水仙花数
        print (number)

这样够清晰吧!!!!

点评

我很赞同!: 4.0
我很赞同!: 4
这样是清晰,但是效率没有小甲鱼老师的高。  发表于 2018-8-4 13:48
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2019-8-5 15:59:42 | 显示全部楼层
变态成什么样的人才会想出如此变态的算法
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2019-9-22 19:22:28 | 显示全部楼层
还是鱼头好 发表于 2017-11-10 22:06
马住,周末继续看……

结合第18讲,第9讲的水仙花数的求法终于看懂了T____T

啊哈哈哈哈哈哈哈哈  我还是要不求甚解  看完了再回来算了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-11-23 23:21:29 | 显示全部楼层
始终不理解"while temp:" 为什么temp小于零就会跳出循环? 为什么不是"while temp>0: "?


以下是我自己的算法
x = 100
while x < 1000:
    a=str(x)
    bai=int(a[0])
    shi=int(a[1])
    ge=int(a[2])
    if x == ge**3+shi**3+bai**3:
        print (x)
    x += 1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-12-14 17:30:03 | 显示全部楼层
长见识了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-30 19:09:14 | 显示全部楼层
本帖最后由 bluesky0476 于 2020-4-16 09:26 编辑

看了半天,明白了,以下是我的理解,为了便于读懂,写得比较详细----------

i在range(100,1000)中,为100-999,i 依次取其中的值,取一个值,把值赋予temp ,即  temp=i ,然后进行一次while 循环运算 ;
sum初始值赋予0,既是对sum进行定义,同时sum也必须为0;

一、以153为例( 即i=153时):
1、temp % 10 : 取个位数(三位数除以10的余数), 如153 运算后取3;
2、sum = 0+3的3次方  =27 ----此时sum为个位的立方和;
3、temp=temp//10: 使位数左移一位,如153/10=15余3,取15;
4、此时,sum==27,i==153,sum!=i,不print(i);
5、返回while循环,此时,while 15(非0),循环继续执行;
6、sum = 27 + (15%10)**3 ,即sum= 27 + 5**3 = 152,----此时sum=  个位数立方和  +   十位数立方和 ;
7、temp=temp//10,即15 // = 10,运算后为temp=1;
8、返回while循环,此时,while 1(非0),循环继续执行;
9、sum =152 + (1%10)**3= 152+1 =153,此时sum=  个位数立方和  +   十位数立方和 + 百位数立方和       (注:1%10=1,因为1除以10,商为0,余数为1,此时取余数1);
10、temp=temp//10 , 即temp=1/10,结果为0,余1,此时temp取0 ;
11、此时,sum ==153,i==153,sum==i----print(i)
12、此时temp为0,继续返回while循环,为 while temp 变为 while 0 , 即i=153时的循环停止。

二、以154为例( 即i=154时):
1、temp % 10 : 取个位数(三位数除以10的余数), 如154 运算后取4;
2、sum = 0+4的3次方  =64 ----此时sum为个位的立方和;
3、temp=temp//10: 使位数左移一位,如154/10=15余4,取15;
4、此时,sum==64 ,i==154 ,sum!=i,不print(i);
5、返回while循环,此时,while 15(非0),循环继续执行;
6、sum = 64 + (15%10)**3 ,即sum= 64 + 5**3 = 189,----此时sum =  个位数立方和  +   十位数立方和 ;
7、temp=temp//10,即15 // = 10,运算后为temp=1;
8、返回while循环,此时,while 1(非0),循环继续执行;
9、sum =189 + (1%10)**3= 189+1 =190,此时sum=  个位数立方和  +   十位数立方和 + 百位数立方和       (注:1%10=1,因为1除以10,商为0,余数为1,此时取余数1);
10、temp=temp//10 , 即temp=1/10,结果为0,余1,此时temp取0 ;
11、此时,sum==190,i==154,sum!=i----不执行print(i)
12、此时temp为0,继续返回while循环,为 while temp 变为 while 0 , 即i=154时的循环停止。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 2 反对 0

使用道具 举报

发表于 2020-2-4 15:05:42 | 显示全部楼层
bluesky0476 发表于 2020-1-30 19:09
看了半天,明白了,以下是我的理解,为了便于读懂,写得比较详细----------

i在range(100,1000)中,为 ...

还是不理解 你说的第3步, 第三步 就是取 百位 和十位的数据吗? 又为什么是往左移动一位?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-4 15:59:49 | 显示全部楼层
vx17707390698 发表于 2020-2-4 15:05
还是不理解 你说的第3步, 第三步 就是取 百位 和十位的数据吗? 又为什么是往左移动一位?

因为//的意思就是  ÷ 除,小数点后舍去,所以如果
temp=153
temp=temp//10
为153//10=15, 余3
取15  (余数3要舍去)
即相当于把153左移了一位,变成了15
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-4 16:07:02 | 显示全部楼层
纠结一天一夜,顿悟了。
*********************************************
for i in range(100, 1000):
    sum = 0
    temp = i
    while temp:
        sum = sum + (temp%10) ** 3
        temp //= 10         # 注意这里要使用地板除哦~
    if sum == i:
        print(i)
******************************************
     sum = sum + (temp%10) ** 3 这个表达式中,temp%10 是为了取得 个位数值(以153为例子),取得了个位数的3
然后将  3  立方后,给sum。 sum=0+3*3=27
      此时,还在整个while 循环体中,需要继续执行   temp //= 10 。 整个表达式为为了将 153,变成 15,3两部分(即:把一个三位数百位、十位与个位分开,变成2个部分,15,3)。现在再数值上,temp=15, 而这个15,再 while temp:中,为真,则这个循环还要继续执行。而,此时因为是继续前面的步骤(此时并不是完全重新开始,而是继续完成前面取值153这个数字,没有完成的循环),此时的temp是15,执行 temp%10 ,取到的值为5(这点特别注意,此时取得的5,其实是 153中的 十位 ,5。了解水仙花的定义可知道,这个十位是目前我们需要的数字就可以了。)现在将 十位的5 进行立方,的到125,此时,sum会进行  sum = sum + (temp%10) ** 3 指令(sum=27(由前面3*3得来)+(15%10)*3=27+125),
   需要注意此时已经不知不觉 将  153中的 个位数3  ,十位数  5,分别进行了 立方计算。并且将2者的立法和 赋值给了 变量 sum
同时,当temp=15时,仍需要执行  temp//=10,此时,temp=1(这是取整)
从而又重新执行 while temp:(因为此时 temp=1,while 语句为真,可执行)
此时 temp=1 ,要知道 1其实是 153 的百位数值。   1%10  此时的余数1(好像小学知识,我也记得了,但应该是这个意思),从而执行 sum=(27+125)+1*3    需要注意 此时 已经将 1,5,3 都分别立方了。
这里面  sum=sum+(temp%10)*3 其实也执行了三次,有点迭代跟新的意思,具体是怎么个逻辑 我说不清,但理解应该是这样子的
此时循环体还需要执行, temp=1  所以 当执行 temp//=10 时候,得到的结果是  0,余1(小学知识,我也忘记了)  好了!此时的temp=0了(前面的地板刷不是取整的意思吗,就是 0)
当最新的temp=0时,while temp:为假。不执行后面的循环。
一直到这个地方!!!!!!while 语句才算停止循环。所以 执行 while 后面的指令  if sum == i:
要知道  temp 是从153 算的,而 temp=i,      sum现在的数值就是 3*3+5*3+1*3=153     if成立,所以 输出。 如此循环。

好了, 对不对 都点个赞吧 。我也是想烂脑袋才看懂的。   


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

使用道具 举报

发表于 2020-4-14 14:23:09 | 显示全部楼层
bluesky0476 发表于 2020-1-30 19:09
看了半天,明白了,以下是我的理解,为了便于读懂,写得比较详细----------

i在range(100,1000)中,为 ...

大佬,请问下这个第4步的print只有当个十百 3个数都加好之后,temp地板除变成0之后不再循环后才执行的吧,还是个位的立方和之后就会执行一次呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-16 09:22:38 | 显示全部楼层
丶hacker丶 发表于 2020-4-14 14:23
大佬,请问下这个第4步的print只有当个十百 3个数都加好之后,temp地板除变成0之后不再循环后才执行的吧 ...

print(i),的确是:只有当个十百 3个数都加好之后,即跳出while循环后才执行的,但前提是sum==i 。

第4步写的就是:     sum!=i , 不print(i)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-2 13:14:50 | 显示全部楼层
bluesky0476 发表于 2020-1-30 19:09
看了半天,明白了,以下是我的理解,为了便于读懂,写得比较详细----------

i在range(100,1000)中,为 ...

“while temp 变为 while 0 , 即i=153时的循环停止”,为啥temp=0,就终止循环了呢?小白一枚。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-3-29 05:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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