问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

如何快速找质数的算法

创作时间:
作者:
@小白创作中心

如何快速找质数的算法

引用
1
来源
1.
https://docs.pingcode.com/baike/1992271

质数是数学中的一个重要概念,其定义为大于1的整数,除了1和它本身以外,没有其他正因数的数。在数学和计算机科学中,质数有许多重要的应用,例如加密算法、随机数生成、数据压缩等。因此,快速找到质数的算法具有重要的研究价值。本文将介绍几种常见的快速找质数的算法,包括埃拉托斯特尼筛法、试除法、分段筛法、线性筛法和AKS算法。

一、埃拉托斯特尼筛法

埃拉托斯特尼筛法是一种经典且高效的算法,用于在一定范围内找出所有质数。其基本思想是从小到大逐一标记出合数,从而筛选出质数。

1、原理介绍

埃拉托斯特尼筛法的基本步骤如下:

  1. 创建一个布尔数组,初始时将所有元素设置为“真”,表示所有数都是质数。
  2. 从最小的质数2开始,将其所有的倍数标记为“假”,表示这些数不是质数。
  3. 找到数组中下一个为“真”的数,这个数就是下一个质数,然后将其所有的倍数标记为“假”。
  4. 重复步骤3,直到数组的末尾。

2、实现步骤

让我们通过一个具体的例子来说明埃拉托斯特尼筛法的实现过程:假设我们要找出从2到30之间的所有质数。

  1. 创建一个布尔数组isPrime,大小为31(因为包含0到30),初始时所有元素都设置为“真”。
  2. 从2开始,将2的倍数(4, 6, 8, 10, …)都标记为“假”。
  3. 找到下一个为“真”的数3,将3的倍数(6, 9, 12, …)都标记为“假”。
  4. 重复上述步骤,直到处理完所有数。

最终,数组中仍然为“真”的位置所对应的数就是质数。

3、代码示例

下面是Python实现埃拉托斯特尼筛法的代码:

def sieve_of_eratosthenes(n):
    is_prime = [True] * (n + 1)
    p = 2
    while (p * p <= n):
        if (is_prime[p] == True):
            for i in range(p * p, n + 1, p):
                is_prime[i] = False
        p += 1
    prime_numbers = [p for p in range(2, n + 1) if is_prime[p]]
    return prime_numbers

## 查找2到30之间的所有质数
print(sieve_of_eratosthenes(30))

二、试除法

试除法是一种简单直观的算法,用于判断一个数是否为质数。其基本思想是尝试用小于该数的所有质数去除它,如果没有发现整除的情况,则该数为质数。

1、原理介绍

试除法的步骤如下:

  1. 对于一个给定的数n,从2到sqrt(n)逐一尝试能否整除n。
  2. 如果发现任何一个数m能够整除n,则n不是质数。
  3. 如果没有发现任何能整除n的数,则n是质数。

2、代码示例

下面是Python实现试除法的代码:

import math

def is_prime(n):
    if n <= 1:
        return False
    for i in range(2, int(math.sqrt(n)) + 1):
        if n % i == 0:
            return False
    return True

## 判断是否是质数
print(is_prime(29))
print(is_prime(30))

三、分段筛法

分段筛法是一种优化的埃拉托斯特尼筛法,适用于找出非常大范围内的质数。其基本思想是将大范围分成若干小段,每次处理一段。

1、原理介绍

分段筛法的步骤如下:

  1. 先用埃拉托斯特尼筛法找出较小范围内的质数(称为基质数)。
  2. 将大范围分成若干小段。
  3. 用基质数筛选每一段,标记出合数。
  4. 合并所有段的结果,得到大范围内的质数。

2、代码示例

下面是Python实现分段筛法的代码:

def segmented_sieve(n):
    limit = int(math.sqrt(n)) + 1
    prime_numbers = sieve_of_eratosthenes(limit)
    low = limit
    high = 2 * limit
    while low < n:
        if high >= n:
            high = n
        mark = [True] * (high - low)
        for prime in prime_numbers:
            low_limit = max(prime * prime, (low + prime - 1) // prime * prime)
            for j in range(low_limit, high, prime):
                mark[j - low] = False
        for i in range(low, high):
            if mark[i - low]:
                prime_numbers.append(i)
        low = low + limit
        high = high + limit
    return prime_numbers

## 查找2到100之间的所有质数
print(segmented_sieve(100))

四、线性筛法

线性筛法是一种更高效的筛选质数的方法,时间复杂度为O(n)。其基本思想是每个合数只会被它最小的质因子筛掉,从而避免了重复计算。

1、原理介绍

线性筛法的步骤如下:

  1. 创建一个布尔数组,初始时将所有元素设置为“真”,表示所有数都是质数。
  2. 从最小的质数2开始,将其所有的倍数标记为“假”。
  3. 继续找下一个质数,将其所有的倍数标记为“假”,但每个合数只会被它最小的质因子筛掉。
  4. 重复上述步骤,直到处理完所有数。

2、代码示例

下面是Python实现线性筛法的代码:

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

## 查找2到30之间的所有质数
print(linear_sieve(30))

五、AKS算法

AKS算法是一种确定性的多项式时间质数判定算法,适用于大数的质数判定。其基本思想是基于多项式同余的性质。

1、原理介绍

AKS算法的步骤如下:

  1. 检查n是否是完全幂,如果是,则n不是质数。
  2. 找到一个合适的r,使得n在模r的情况下满足一定的条件。
  3. 检查1到r之间的数,看是否存在满足一定条件的a。
  4. 如果上述条件都满足,则n是质数,否则n不是质数。

2、代码示例

由于AKS算法较为复杂,这里仅提供一个简化版的实现代码:

def is_prime_aks(n):
    if n <= 1:
        return False
    if n <= 3:
        return True
    if n % 2 == 0 or n % 3 == 0:
        return False
    i = 5
    while i * i <= n:
        if n % i == 0 or n % (i + 2) == 0:
            return False
        i += 6
    return True

## 判断是否是质数
print(is_prime_aks(29))
print(is_prime_aks(30))

总结

快速找质数的算法有很多,每种算法都有其适用的场景和优缺点。埃拉托斯特尼筛法适合中小范围内的质数筛选,试除法适合单个数的质数判定,分段筛法适合大范围的质数筛选,线性筛法在时间复杂度上具有优势,而AKS算法则适用于大数的质数判定。在实际应用中,可以根据具体需求选择合适的算法。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号