[Python]质数相关

582 阅读3分钟

写在前面的话

  • 基于Python 3.7
  • 基础数学(小学5年级内容),正好儿子上到这个阶段就写一下
  • 涉及部分python语法

题目

  • 相关的题目可以是判断一个数是否是质数
  • 取出0~N之间的质数等等

质数特性

  • 在大于1的自然数中,除了1和它本身以外不再有其他因数
  • 唯一的偶质数是2
  • 0和1都不是质数

思路1

将一个数从2除到N-1遇到能整除的就不是素数,反之就是。

def prime_list(n):
    dest_list=[]
    for i in range(2,n+1):
        for j in range(2,i):
            if i%j==0:
                break
        else:
            dest_list.append(i)
    return dest_list
print(prime_list(100))

image.png

for else

上述代码中有一段是for else,这个基础语法一般提的不多,但的确有用。我们来看两个例子。

for i in [1,2,3]:
    if i%2==0:
        break
    else:
        print(i)
else:
    print('hello')
# i=1 打印
# i=2 break
# else没有打印

输出:1

for i in [1,2,3]:
    if i%4==0:
        break
    else:
        print(i)
else:
    print('hello')
# i=1,2,3均print,for循环做完了
# else执行了

输出: 1 2 3 hello

总结:如果for正常结束,就执行else),若中途遇到break),就不执行else

思路2

我们方法一的思路,时间复杂度好像是O(n²),2层循环,虽然会break,但效率还是很低的。100000以内的求解竟然要38.6s,100w我的电脑都要运行好久。

image.png

这个时候我们要看下质数的理论了。 其实我们发现我们求解质数的时候,根本不需要从2除到N-1,当除数大于商的时候我们就不用计算了。

以13为例: 13÷2=6--1 13÷3=4-1 13÷4=3-1 #到这里我们不用算了 13÷5=2-3 13÷6=2-1

用数学的话来说我们只需除到平方根就好了。

import math
def prime_list(n):
    dest_list=[]
    for i in range(2,n+1):
        for j in range(2,int(math.sqrt(i))+1):
            if i%j==0:
                break
        else:
            dest_list.append(i)
    return dest_list
print(prime_list(100))

我们来看下时间,我们发现同样的代码,节省了大量时间,10w数据之用了276ms,可以测试100w花了5s。1000w数据测试约耗时2分半。

思路3

那是否还能提高更多呢?可以的! 还是要用到素数相关的理论:对于大于3的质数,只分布在6x-1和6x+1两数列中(x为非0自然数)。即都在6的倍数的两侧。

def prime_list(n):
    list1=[]
    for i in range(2,n+1):
        if i == 2 or i == 3 or i == 5:
            list1.append(i)
        else:
            if i % 6 == 1 or i % 6 ==5:
                for j in range(2,int(math.sqrt(i)+1)):
                    if i%j ==0:
                        break
                else:
                    list1.append(i)
    return list1
print(prime_list(1000000))

质数相关的理论

哥德巴赫猜想:任何大于5的奇数都是三个素数之和 -衍生:任何一个大于2的偶数都是两个素数之和 伯特兰猜想:对于任意正整数n>1,存在一个素数p,使得n<p<2n 孪生素数猜想:存在无穷多的形如p和p+2的素数对 n2+1 猜想:存在无穷多个形如n2+1的素数,其中n是正整数