一、前言
今天学习视频时课后作业是找出1000以内既是素数又是回文数的数,写代码这个很容易,结果一运行遇到了bug,输出结果跟预期不一样,调试了快30min,再接着一通搜索和回看视频才发现问题所在。所以特地写下来,方便以后查看。问题的关键是判断素数过程中for…else的用法上(具体看后面代码)
二、实现判断素数的功能
质数(Prime number),又称素数,指在大于1的自然数中,除了1和该数自身外,无法被其他自然数整除的数(也可定义为只有1与该数本身两个因数的数)。via——Wikipedia
所以采用穷举法只要在2~n-1的区间,没有一个数能整除n,那么n就是素数。
对2-n-1区间进行合理优化,假设x*y=n(x<=y),那么当x和y相等时,x有最大值。即x=y=sqrt(n),所以x的区间就可以限制为2~sqrt(n)+1。还有疑问,可以在再多想想,纸上算一算。
因为这里要用到sqrt()方法,所以需要导入math模块。
不多说,直接上代码:
# 求解1000以内的所有素数,正确版本 import math num = 2 count = 0 list_s = [] max_d = 1000 while num < max_d: length = int(math.sqrt(num)+1) # 对遍历范围进行合理优化 for i in range(2,length): # 注意从2开始 if num % i == 0: break else: # 这里的else跟for对齐,而不是跟if,表示只有for顺利执行时,else才执行 count += 1 list_s.append(num) # 存入列表 num += 1 if count == 0: print(max_d,'以内没有素数') else: print(max_d,'以内的素数有',count,'个,分别是:',list_s)
输出结果:
这个代码完全没有问题,然后下面给出一个有问题的代码:
# 求解40以内的所有素数,错误版本 import math num = 2 count = 0 list_s = [] max_d = 40 while num < max_d: length = int(math.sqrt(num)+1) # 对遍历范围进行合理优化 for i in range(2,length): # 注意从2开始 if num % i == 0: break else: # 这里的else跟if对齐,会导致一个素数会被写入int(math.sqrt(num))-1次,同时一些非素数也会被当做素数 count += 1 list_s.append(num) # 存入列表 num += 1 if count == 0: print(max_d,'以内没有素数') else: print(max_d,'以内的素数有',count,'个,分别是:',list_s)
输出结果:
所以,一定要认真对待循环中else对齐问题。这个在解决素数问题中很重要。小结一下while…else和for…else
只有循环完所有次数,才会执行 else ,循环体中有continue存在,也不影响else执行。
一旦循环体中触发了break ,就会阻止 else 语句块的执行。
三、实现判断回文数的功能
回文数即从左到右和从右到左一样。如:12321。
方法:
把已知的num1数反过来,得到num2,如123变为321,采用//10 %10 *10等运算操作,其中还要借助一个临时变量tmp
判断如果num1 == num 2,则num1是回文数,反之不是
代码如下:
# 求解1000以内的所有回文数 num = 0 # 这里num从0开始 list_h = [] max_d = 10000 count = 0 while num < max_d: tmp = num num_p = 0 while tmp != 0: num_p = num_p*10 + tmp % 10 tmp //= 10 if num_p == num: list_h.append(num) count += 1 num += 1 if count == 0: print(max_d,'以内没有回文数') else: print(max_d,'以内的回文数有',count,'个,分别是:',list_h)
更新:对于判断回文数或者回文字符串,采用双端队列的数据结构,会非常简单。实现如下:
from collections import deque def palindrome(word): dq = deque(word) while len(dq) > 1: if dq.pop() != dq.popleft(): return False return True if __name__ == '__main__': max_num = 10000 for i in range(max_num): s = str(i) if palindrome(s): print(i, end=',')
四、实现同时判断回文数和质数
需要选择是否嵌套以及先判断回文还是先判断素数,所以又四个版本。大家可以自己思考每个版本的性能上有无区别,占用空间有无区别。因为我也没有太想明白,所以没有放上来。
我写了四个版本,都能实现需求。不过从性能上,在我测试的100-1000000区间,采用嵌套的先求解回文再判断素数要快一些。
不多说,四个版本的代码全部在写下面,可以自行删掉相应的'''标记进行测试。
''' # 版本一、求1000以内的回文素数,多层嵌套,先求素数后回文数 import math num = 2 count = 0 list_s = [] list_sh = [] max_d = 1000 while num < max_d: length = int(math.sqrt(num)+1) for i in range(2,length): if num % i == 0: break else: list_s.append(num) tmp = num num_p = 0 while tmp != 0: num_p = num_p * 10 + tmp % 10 tmp //= 10 if num == num_p: list_sh.append(num) count +=1 num += 1 print(max_d,'以内的素数有:',list_s) if count == 0: print(max_d,'以内没有既是素数又是回文数的数') else: print(max_d,'以内既是素数又是回文数的数有',count,'个,分别是:',list_sh) ''' ''' # 版本二、求1000以内的回文素数,多层嵌套,先求回文数后求素数 import math num = 2 count = 0 list_h = [] list_hs = [] max_d = 1000 while num < max_d: tmp = num num_p = 0 while tmp != 0: num_p = num_p * 10 + tmp % 10 tmp //= 10 if num == num_p: list_h.append(num) length = int(math.sqrt(num)+1) for i in range(2,length): if num % i == 0: break else: list_hs.append(num) count +=1 num += 1 print(max_d,'以内的素数有:',list_h) if count == 0: print(max_d,'以内没有既是素数又是回文数的数') else: print(max_d,'以内既是素数又是回文数的数有',count,'个,分别是:',list_hs) ''' ''' # 版本三、求1000以内的回文素数,先求素数再求回文数 import math num = 2 list_s = [] max_d = 1000 while num < max_d: length = int(math.sqrt(num)+1) for i in range(2,length): if num % i == 0: break else: # 注意这里的else是和for对齐 list_s.append(num) num += 1 count = 0 list_sh = [] for i in list_s: tmp = i num_p = 0 while tmp != 0: num_p = num_p*10 + tmp % 10 tmp //= 10 if num_p == i: list_sh.append(i) count += 1 print(max_d,'以内的素数有:',list_s) if count == 0: print(max_d,'以内没有既是素数又是回文数的数') else: print(max_d,'以内既是素数又是回文数的数有',count,'个,分别是:',list_sh) ''' ''' # 版本四、求1000以内的回文素数,先求回文数,再求素数 import math num = 2 list_h = [] max_d = 10000 while num < max_d: tmp = num num_p = 0 while tmp != 0: num_p = num_p*10 + tmp % 10 tmp //= 10 if num_p == num: list_h.append(num) num += 1 count = 0 list_sh = [] for hn in list_h: length = int(math.sqrt(hn)+1) for i in range(2,length): if hn % i == 0: break else: # 注意这里的else是和for对齐 list_sh.append(hn) count += 1 print(max_d,'以内的回文数有:',list_h) if count == 0: print(max_d,'以内没有既是素数又是回文数的数') else: print(max_d,'以内既是素数又是回文数的数有',count,'个,分别是:',list_sh) '''
五、总结
这个过程帮助自己更加深刻的理解了if…elif…else 、for…else和while…else以后使用时会更加注意。
以上这篇解决Python中回文数和质数的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
Python,回文数,质数
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 雨林唱片《赏》新曲+精选集SACD版[ISO][2.3G]
- 罗大佑与OK男女合唱团.1995-再会吧!素兰【音乐工厂】【WAV+CUE】
- 草蜢.1993-宝贝对不起(国)【宝丽金】【WAV+CUE】
- 杨培安.2009-抒·情(EP)【擎天娱乐】【WAV+CUE】
- 周慧敏《EndlessDream》[WAV+CUE]
- 彭芳《纯色角3》2007[WAV+CUE]
- 江志丰2008-今生为你[豪记][WAV+CUE]
- 罗大佑1994《恋曲2000》音乐工厂[WAV+CUE][1G]
- 群星《一首歌一个故事》赵英俊某些作品重唱企划[FLAC分轨][1G]
- 群星《网易云英文歌曲播放量TOP100》[MP3][1G]
- 方大同.2024-梦想家TheDreamer【赋音乐】【FLAC分轨】
- 李慧珍.2007-爱死了【华谊兄弟】【WAV+CUE】
- 王大文.2019-国际太空站【环球】【FLAC分轨】
- 群星《2022超好听的十倍音质网络歌曲(163)》U盘音乐[WAV分轨][1.1G]
- 童丽《啼笑姻缘》头版限量编号24K金碟[低速原抓WAV+CUE][1.1G]