本文始发于个人公众号:TechFlow,原创不易,求个关注
今天这篇是算法与数据结构专题的第23篇文章,我们继续数论相关的算法,来看看大名鼎鼎的埃式筛法。
我们都知道在数学领域,素数非常重要,有海量的公式和研究关于素数,比如那个非常著名至今没有人解出来的哥德巴赫猜想。和数学领域一样,素数在信息领域也非常重要,有着大量的应用。举个简单的例子,很多安全加密算法也是利用的质数。我们想要利用素数去进行各种计算之前,总是要先找到素数。所以这就有了一个最简单也最不简单的问题,我们怎么样来寻找素数呢?
判断素数
寻找素数最朴素的方法当然是一个一个遍历,我们依次遍历每一个数,然后分别判断是否是素数。所以问题的核心又回到了判断素数上,那么怎么判断一个数是不是素数呢?
素数的性质只有一个,就是只有1和它本身这两个因数,我们要判断素数也只能利用这个性质。所以可以想到,假如我们要判断n是否是素数,可以从2开始遍历到n-1,如果这n-1个数都不能整除n,那么说明n就是素数。这个我没记错在C语言的练习题当中出现过,总之非常简单,可以说是最简单的算法了。
def is_prime(n):
for i in range(2, n):
if n % i == 0:
return False
return n != 1
显然,这个算法是可以优化的,比如当n是偶数的时候,我们根本不需要循环,除了2意外的偶数一定是合数。再比如,我们循环的上界其实也没有必要到n-1,到 n \sqrt{n} n就可以了。因为因数如果存在一定是成对出现的,如果存在小于根号n的因数,那么n除以它一定大于根号n。
这个改进也很简单,稍作改动即可:
def is_prime(n):
if n % 2 ==