【算法】欧拉筛 输出任意范围内的质数

总所周知,质数(prime number)又称素数,除了1自身外,不能被其他的自然数整除。

那么我们今天就来看看一个简单的寻找素数的算法,欧拉筛。欧拉筛是在埃氏筛的基础上做了一定的改进,大幅降低时间复杂度。

欧拉筛

输入

  • 区间范围n

输出

  • 素数列表

思想

  • 通过打表的方式,构建素数表,这张表包含了n个元素,包括素数和合数
  • 素数是无法通过其他素数相乘得到的,利用这一原理,可以将所有能够被素数相乘得到的值设置为合数

过程

  • 创建一个大小为n的列表isPrime,元素值代表是否为素数。
  • 创建一个新的可变列表prime,元素值代表素数
  • 遍历isPrime,若元素值为1,则将其加入prime列表。
  • 将该元素与prime中的所有素数相乘:
    • 若该元素为素数,那么会遍历prime列表,得到的结果是最小素数相乘的合数
    • 若该元素为合数,那么将为其添加新的最小质数,直到遇到初始质数。(同样也是最小质数相乘)

算法

n=int(1e5+1)
prime=[]
isPrime=[1 for i in range(n+1)]
# 欧拉筛构建1-n的所有质数
for i in range(2,n+1):
    if isPrime[i]==1:
        # 质数加入队列
        prime.append(i)

    # 删除质数集构成的合数
    for j in range(len(prime)):
        if prime[j]*i<n:
            # 合数去掉了
            isPrime[prime[j]*i]=0
        else:
            break
        # 通过最小质数来构建即可
        if i%prime[j]==0:
            # 当然第一次遇到还是要乘上去的,这样才会倍增
            break
print(prime)
len(prime) # 664579

复杂度

时间复杂度约等于 O ( N ) O(N) O(N),它只对每个元素遍历一次。

你可能感兴趣的:(算法与数据结构,Python,算法,python,开发语言)