📌  相关文章
📜  numero primos (1)

📅  最后修改于: 2023-12-03 15:03:18.467000             🧑  作者: Mango

质数(Primes)介绍和算法实现

质数是指只能整除1和本身的自然数。例如,2、3、5、7、11、13等都是质数。已知质数有无数个,但无法给出全部质数。

算法实现:

1. 埃拉托斯特尼筛法(Sieve of Eratosthenes)

该算法基于一个简单的想法,如果一个数是质数,则它的倍数一定不是质数。因此,我们可以从数字2开始,将每个质数的倍数标记为非质数。在处理完全部的质数后,所有未被标记成非质数的数字都是质数。

def eratosthenes_sieve(n):
    is_prime = [True for i in range(n+1)]
    is_prime[0], is_prime[1] = False, False
    for i in range(2, int(n**0.5)+1):
        if is_prime[i]:
            for j in range(i*i, n+1, i):
                is_prime[j] = False
    
    primes = []
    for i in range(2, n+1):
        if is_prime[i]:
            primes.append(i)
    
    return primes

print(eratosthenes_sieve(20)) # [2, 3, 5, 7, 11, 13, 17, 19]
2. 欧拉筛法(Sieve of Euler)

和埃拉托斯特尼筛法类似,欧拉筛法也是基于筛选质数倍数的想法。不同之处在于,当处理某个数时,我们可以去除其所有的质数因子,这样可以避免重复标记。

def euler_sieve(n):
    is_prime = [True for i in range(n+1)]
    primes = []
    for i in range(2, n+1):
        if is_prime[i]:
            primes.append(i)
        for p in primes:
            if i*p > n:
                break
            is_prime[i*p] = False
            if i % p == 0:  # 已经处理完p的倍数
                break
            
    return primes

print(euler_sieve(20)) # [2, 3, 5, 7, 11, 13, 17, 19]
3. 线性筛法(Linear-time Sieve)

线性筛法是欧拉筛法的优化,可以将时间复杂度降至O(n)。该算法和欧拉筛法类似,但是在处理某个数i时,会用其最小质因子p[i]去筛选i*p[j],这样避免了对j=1到i-1的所有非质数进行处理。

def linear_sieve(n):
    is_prime = [True for i in range(n+1)]
    primes = []
    p = [0 for i in range(n+1)]
    for i in range(2, n+1):
        if is_prime[i]:
            primes.append(i)
            p[i] = i
        for j in range(len(primes)):
            if primes[j]*i > n:
                break
            is_prime[primes[j]*i] = False
            p[primes[j]*i] = primes[j]
            if i % primes[j] == 0:
                break
    
    return primes

print(linear_sieve(20)) # [2, 3, 5, 7, 11, 13, 17, 19]

以上三种算法可以快速地求出小于等于n的所有质数。在实际应用中,我们可以通过查表或者预处理来加速素数的查找。