埃拉托色尼筛法--质数

埃拉托色尼筛法是一种经典的求解素数的算法。其基本思想是通过将素数的倍数标记为非素数,从而留下素数。它的时间复杂度为 O(nlog⁡log⁡n),是非常高效的。

下面是埃拉托色尼筛法的 Java 实现和详细解释:

代码实现

import java.util.Arrays;

public class SieveOfEratosthenes {
    public static void main(String[] args) {
        int n = 50; // 查找小于等于 n 的所有质数
        boolean[] isPrime = sieveOfEratosthenes(n);

        // 打印所有的质数
        System.out.println("质数小于等于 " + n + " 的所有质数为:");
        for (int i = 2; i <= n; i++) {
            if (isPrime[i]) {
                System.out.print(i + " ");
            }
        }
    }

    public static boolean[] sieveOfEratosthenes(int n) {
        // 初始化一个布尔数组,默认所有值为 true
        boolean[] isPrime = new boolean[n + 1];
        Arrays.fill(isPrime, true);

        // 0 和 1 不是质数
        isPrime[0] = false;
        isPrime[1] = false;

        // 从 2 开始,对每个数字进行筛选
        for (int i = 2; i * i <= n; i++) {
            if (isPrime[i]) {
                // 将 i 的所有倍数标记为非质数
                for (int j = i * i; j <= n; j += i) {
                    isPrime[j] = false;
                }
            }
        }

        return isPrime;
    }
}

代码解析

  1. 布尔数组初始化

    • 使用布尔数组 isPrime 表示一个数是否是质数。
    • 默认情况下,所有数都假设是质数(true),然后逐步筛去非质数。
  2. 筛选逻辑

    • 从 2 开始,检查每个数是否为质数。

      如果一个数 \(i\)是质数,则从 \(i^2\) 开始,将其所有倍数\((i×k ,其中 k≥2)\)标记为非质数。

      为什么从\(i^2\)开始?因为比\(i^2\)小的倍数已经在之前被标记。

  3. 循环条件优化

    • 外层循环只需要检查到 \(\sqrt{n}\),因为超过这个范围的倍数已经在之前被标记。
  4. 时间复杂度

    • 外层循环运行到 \(\sqrt{n}\),内层循环处理每个素数的倍数。总体复杂度为 O(nlog⁡log⁡n)。

示例输出

运行上述代码,当 n=50 时,输出如下:

复制代码质数小于等于 50 的所有质数为:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47

优点

  • 算法简单高效,适合大规模素数筛选。
  • 使用空间 O(n) 存储布尔数组。
posted @ 2024-12-02 16:31  发光的反派  阅读(79)  评论(1)    收藏  举报