当前位置: 首页 > 编程笔记 >

解决Python中回文数和质数的问题

范安歌
2023-03-14
本文向大家介绍解决Python中回文数和质数的问题,包括了解决Python中回文数和质数的问题的使用技巧和注意事项,需要的朋友参考一下

一、前言

今天学习视频时课后作业是找出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 解决函数返回return的问题,包括了python 解决函数返回return的问题的使用技巧和注意事项,需要的朋友参考一下 定义一个带返回值的函数,需要使用return语句在调用这个函数时返回一个目标值,当没有return时,函数默认返回None。 分析下面两个程序: out: 2017-9-25 out: 2017-9-25 None 对于第一个程序,仅仅调用了'no

  • 本文向大家介绍解决Python传递中文参数的问题,包括了解决Python传递中文参数的问题的使用技巧和注意事项,需要的朋友参考一下 今天有个需要需要传递中文参数给URL 但是在GBK环境下的脚本传递GBK的参数老是给我报UNICODE的解码错误。烦的很。 所以我们果断选择用urlencode来处理中文, 由于国内外网站编码不同,国内是GBK的,国外是UTF8的。 这样我就得到了GBK的url编码,

  • 问题内容: 我对使用python进行函数式编程感兴趣,并且正在研究Mary Rose Cook的博客文章 函数式编程的实用介绍 。 显然,它是用python 2编写的,如下所示: 在Python 3中产生以下结果: 我有两个问题: 为什么会这样呢? 除了将地图对象转换为列表然后使用numpy之外,还有其他解决方案吗? 问题答案: 如所述,在迁移指南中, 在Python 2中,map()返回一个列表

  • 本文向大家介绍Python os模块中的isfile()和isdir()函数均返回false问题解决方法,包括了Python os模块中的isfile()和isdir()函数均返回false问题解决方法的使用技巧和注意事项,需要的朋友参考一下 今天在写一个linux下自动备份指定目录下的所有目录的脚本时,遇到了一个问题,由于我是需要备份目录,所以,需要判断扫描的文件是否为目录,当我用os.path

  • 问题内容: 我正在尝试编写一个程序来查找非常大的最大素数,并且尝试了几种方法,但均获得了不同的成功。到目前为止,我发现的所有速度都令人难以置信。我有一个想法,想知道这是否是一种有效的方法: 这种方法将需要输入,并且将执行以下操作: 200-> 100-> 50-> 25-> 5(返回) 90-> 45-> 15-> 5(返回) 它将currentNum反复除以最小的可除数(通常为2或3),直到cu

  • 本文向大家介绍解决python中os.listdir()函数读取文件夹下文件的乱序和排序问题,包括了解决python中os.listdir()函数读取文件夹下文件的乱序和排序问题的使用技巧和注意事项,需要的朋友参考一下 1. os.listdir()概述 os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表。 例如: 注意:os.listdir()返回的文件名不一定是顺