Python练习(9)

问题描述

金蝉素数:
某古寺的一块石碑上依稀刻有一些神秘的自然数。 专家研究发现:这些数是由1,3,5,7,9这5个奇数字排列组成的5位素数,同时去掉它的最高位与最低位数字后的3位数还是素数,同时去掉它的高二位与低二位数字后的一位数还是素数。因此人们把这些神秘的素数称为金蝉素数,喻意金蝉脱壳之后仍为美丽的金蝉。
试求出石碑上的金蝉素数

问题分析

  • 首先构造一个判断素数的函数,之前做过
  • 如何生成只含有13579的五位数,要写出所有排列,难点
  • 要生成去掉前后各一位后剩下的三位数,这个之前做过,reduce(lambda x,y:x*10+y, list[1:4])

代码

#构造一个判断素数的函数

def sushu(n):             
    a=0
    for k in range(2,n):
        if n%k==0:
            a+=1
    if a==0:
        return True
    
    
c=[1,3,5,7,9]

def chachao(x):
    for i in range(10000,x):           #没想到如何直接生成这样的五位数,所以遍历所有的五位数,用排除法
        l=0
        if sushu(i):
            for j in str(i):
                if (int(j) not in c):   #判断 j 是否在五个数内,排除不是由这五个数组成的数
                    l+=1
            if l==0:
                b=[int(j) for j in str(i)]  #但生成的数会有11357等这样重复的数字,仍不符合要求
                if len(b)==len(set(b)):     #用一个set函数,生成不重复数组,排除掉11357这样重复的数字
                    m=reduce(lambda x, y: x*10+y, b[1:4])  #生成剩下的三位数
                    if sushu(m):
                        print i

chachao(99999)
#结果
13597
15937
51973
53791
57193  #中间位为1,不符合要求
75931
79531
91573
95713

上面的结果虽然写出来了,但有几个缺点:

  • 素数判断函数,只需遍历到该数的平方根即可(2,sqrt.(n)+1)
  • 数的生成方法用了排除法,需要遍历所有的五位数然后找到符合的,导致运行速度超级慢;
  • 没有考虑去掉前后各两位而剩下一位数的情况,即1在中位的情况,1不是素数

别人家的超简洁代码

def isPrimeNum(n):
    for k in range(2, int(math.sqrt(n) + 1)):      #取值范围缩小到平方根+1,可以节省时间
        if n % k == 0: 
            return False
    return True

from itertools import permutations
for p in permutations([1,3,5,7,9], 5):    #惊叹不已!利用permutation函数,直接生成符合条件的五位数,简单直接
    for l in (p[1:-1], p[::2], p):        #切片的运用,又和for循环结合,方便快捷,
        s = reduce(lambda x, y: 10 * x + y, l) 
        if not isPrimeNum(s): 
            break
    else:
        print p 

看完后就是羡慕,这么简洁的代码,何时能写出来,好多条件目前自己是不具备的:

  • 对python基础函数的了解,需要积累,此题中比如切片、permutations函数事半功倍
  • 对语言结构的巧妙布置,此题中 for循环与三个切片的结合就省了好多行

知识积累:

  • 切片
    p[::2] 是从头开始,每隔两个元素取一次
    p[:10:2] 前十个元素,每个两个取一次

  • 迭代器的使用 from itertools import permutations
    permutations([p],r);返回p中任意取r个元素做排列的元组的迭代器
    combinations(iterable,r);创建一个迭代器,返回iterable中所有长度为r的子序列,返回的子序列中的项按输入iterable中的顺序排序,不重复
    其他迭代器函数:
    https://blog.csdn.net/neweastsun/article/details/51965226

参考资料:
https://blog.csdn.net/u010019717/article/details/51450965#3-金蝉素数-中

猜你喜欢

转载自blog.csdn.net/qq_43243022/article/details/82940246