【100个python算法超详细讲解@谷哥技术】
1.问题描述
请从小到大输出所有4位数的可逆素数。
可逆素数是指一个素数将其各位数字的顺序倒过来构成的反序数也是素数。
2.问题分析
通过前面几节的分析,相信读者对求素数的方法已经很熟悉了。本题要求的是可逆
素数,根据问题描述可知,题目的难点已经不在于判断一个数是否为素数,而在于如何
求一个整数的反序数。
求一个整数的反序数可按照如下的操作步骤进行。
(1)从该整数的最后一位开始,依次向前截取当前整数的最后一位数字。每截取一
次,整数的位数减少一位。
(2)每次都将新截取到的数字作为其反序数的最后一位(个位),然后与上一次生
成的反序数乘以10以后的数值相加。
(3)如此进行下去,原来整数的数字被从低位到高位不断地截取,依次形成其反序
数中从高位到低位的各位数字。
下面以4位整数1234为例说明反序数的生成过程。
(1)截取个位4,原整数变为123,新生成的反序数为4。
1234→0*10+4=4
(2)截取当前整数的个位3,原整数变为12,用3与上一次生成的反序数4乘以10后
的数值相加,则新生成的反序数为43。
123→4*10+3=43
(3)截取当前整数的个位2,原整数变为1,用2与上一次生成的反序数43乘以10后
的数值相加,新生成的反序数为432。
12→43*10+2=432
(4)截取当前整数的个位1,用1与上一次生成的反序数432乘以10后的数值相加,
新生成的反序数为4321。
1→432*10+1=4321
最后得到1234的反序数为4321。
3.算法设计
解决该问题的算法可以使用穷举法,对所有的4位整数及其相应的反序数都依次进行
判断。当该整数本身和其反序数都是素数时,该整数即为可逆素数,此时可以将该整数
打印输出。
判断一个整数是否为素数的方法在前面已经多次用到,此处仍可以使用函数来完成
素数的判断。将函数名设为fun,在其中判断传进来的形参是否为素数,如果是素数则返
回1,否则返回0。该函数已经多次使用过,故此处不再详述,有问题的读者可参考5.2节
及5.3节中对fun()函数的说明。
算法的核心是如何穷举所有的4位整数及其对应的反序数。由于是4位整数,因此算
法设计时可以使用四重嵌套循环,每重循环对应一个数位。当所有循环执行完毕后,也
就完成了对所有4位整数的迭代。
显然,第1重循环对应的是4位整数的千位,同时也是其反序数的个位;第2重循环对
应的是4位整数的百位,同时也是其反序数的十位;第3重循环对应的是4位整数的十位,
同时也是其反序数的百位;第4重循环(也是最内层循环)对应的是4位整数的个位,同
时也是其反序数的千位。这样,每次在最内层循环的循环体内都可以得到用4个循环变量
组成的一个4位整数及其对应的反序数,我们只需判断这两个整数是否为素数即可,如果
它们都为素数,则输出原4位整数,否则不输出。
程序无输入,输出时每行输出10个可逆素数。
4.确定程序框架
程序的主框架为四重循环,具体如下:
for a in range(1, 9+1): # 千位
for b in range(0, 9+1): # 百位
for c in range(0, 9+1): # 十位
for d in range(1, 9+1): # 个位
# 判断4位整数是否为素数
# 判断4位整数的反序数是否为素数
# 如果该4位整数及其反序数都为素数,则打印该4位整数
程序的流程图如图5.7所示。
5.完整的程序
根据上面的分析,编写程序如下:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @author : liuhefei
# @desc: 可逆素数
import math
# 判断素数
def fun(n):
if n <= 1:
return 0; # n<1时显然不是素数,故返回0
if n == 2:
return 1 # n=2,是素数,返回1
if n % 2 == 0:
return 0 # n是偶数,不是素数,返回0
for i in range(3, int(math.sqrt(n) + 1)):
if n % i == 0:
return 0 # n是奇数,不是素数,返回0
i += 2
return 1 # n是除2以外的素数,返回1
if __name__=="__main__":
count = 0 # 计数器
# 穷举法
for a in range(1, 9+1): # 千位
for b in range(0, 9+1): # 百位
for c in range(0, 9+1): # 十位
for d in range(1, 9+1): # 个位
if fun(a*1000+b*100+c*10+d): # 判断4位整数是否为素数
# 判断4位逆序的整数是否为素数
if fun(a+b*10+c*100+d*1000):
if count % 10 == 0: # 每10个数就换行
print()
print("%d " %(a*1000+b*100+c*10+d), end="")
count += 1
print("\n4位可逆素数共有%d个" %count)
对程序的说明如下:
·在上面的程序中使用了四重循环,有4个循环变量a、b、c、d。由于要求是4位整
数,因此a从1开始取值,其取值范围为[1,9]。又因为个位为0的4位数肯定不是素数,因此
d也从1开始取值,其取值范围为[1,9]。
·使用a、b、c、d 4个循环变量可以将4位整数表示为a*1000+b*100+c*10+d,其反序
数为a+b*10+c*100+d*1000。
·程序中使用count变量控制每行输出10个整数。
6.运行结果
在PyCharm下运行程序,结果如图5.8所示。
7.拓展训练
求1000以内的孪生素数。孪生素数是指:若a为素数,且a+2也是素数,则素数a和a+2
称为孪生素数。