解决Python中回文数和质数的问题
作者:Jock2018 发布时间:2021-03-07 02:51:23
一、前言
今天学习视频时课后作业是找出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以后使用时会更加注意。
来源:https://blog.csdn.net/qq_27283619/article/details/86628444


猜你喜欢
- 首先打开网站https://www.zymk.cn/1/37988.html打开开发者工具选择XHR标签页,没有找到什么再查看一下这些图片的
- 列表解析——用来动态地创建列表[expr for iter_var in iterable if cond_expr]例子一:map(lam
- 本文测试环境:CentOS 7 64-bit Minimal MySQL 5.7配置 yum 源在 https://dev.mysql.co
- centos下安装配置phpmyadmin,我花了二个晚上,郁闷的我不行,配置phpmyadmin简单吧,很简单,我刚工作的时候,就配置过,
- 注:答案一般在网上都能够找到。1.对if __name__ == 'main'的理解陈述2.python是如何进行内存管理的
- 前言:相信大家在童年或者生活中都玩过石头剪刀布这个游戏,这个游戏需要两个及以上的人。而今天,网上也实现了石头剪刀布的游戏。通过初步学习pyt
- 废话不多说。直接上代码:sock_post.php:<?phpfunction sock_post($url, $data='
- 分页查询是经常能够遇到的问题,我们首先看看分页查询存在的理由:方便用户:用户不可能一次察看所有数据,所以一页一页的翻看比较好。提高性能:一次
- 做开发中难免时间类型之间的转换, 最近就发现前端js和后端django经常要用到这个转换, 其中jsDate.now()精确到毫秒,而Pyt
- 本文实例讲述了Go语言使用sort包对任意类型元素的集合进行排序的方法。分享给大家供大家参考。具体如下:使用sort包的函数进行排序时,集合
- 前言正则表达式是文本处理领域中的一个强大的工具,它可以让文本处理的能力呈指数级的提升,如果一款文本编辑器不支持正则表达式,那么它就算不上是一
- 函数签名对象,表示调用函数的方式,即定义了函数的输入和输出。在Python中,可以使用标准库inspect的一些方法或类,来操作或创建函数签
- 这个间歇性向上滚动js代码很适合做广告展示,友情链接等等。与平常的无缝向上连续滚动不同的是它每滚动一个就会停顿一会儿。<!DOCTYP
- 前言:相比大家都听过自动化生产线、自动化办公等词汇,在没有人工干预的情况下,机器可以自己完成各项任务,这大大提升了工作效率。编程世界里有各种
- 代码如下:ALTER proc [dbo].[sp_common_paypal_AddInfo] ( @paypalsql va
- 我们知道 Django Auth 应用一般用在用户的登录注册上,用于判断当前的用户是否合法,从而可以帮助开发者快速的构建用户系统,那么 Au
- 功能:扫描当前目录下所有CSV文件并对其中文件进行统计,输出统计值到CSV文件pip install pandasimport pandas
- 列表渲染 key 的原理和作用key就是为该节点做身份标识,如果对key绑定index的值,那么很容易出现问题:1.若对数据进行:逆序添加、
- 进程进程是操作系统分配资源的基本单元,是程序隔离的边界。进程和程序程序只是一组指令的集合,它本身没有任何运行的含义,它是静态的。进程程序的执
- #当前文件的路径pwd = os.getcwd()#当前文件的父路径father_path=os.path.abspath(os.path.