用Java设计一个素数的判断与统计

下面给你一套从基础到进阶的完整方案:用 Java 实现 素数判断 + 素数统计,并逐步优化性能 👇


一、什么是素数?

👉 素数(Prime):只能被 1 和自身整除的数(且 ≥ 2)

例如:

  • ✅ 2, 3, 5, 7, 11
  • ❌ 4, 6, 8, 9

二、基础版:判断一个数是否为素数

✅ 方法1:暴力法(入门)

public static boolean isPrime(int n) {
    if (n < 2) return false;

    for (int i = 2; i < n; i++) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

👉 问题:效率低(O(n))


✅ 方法2:优化到 √n(推荐)

👉 原理:
如果 n 有因子,一定成对出现,例如:

36 = 6 × 6

所以只需判断到 √n

public static boolean isPrime(int n) {
    if (n < 2) return false;

    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

👉 时间复杂度:O(√n)(非常常用)


三、统计区间内的素数

✅ 方法1:逐个判断(简单)

public static int countPrimes(int n) {
    int count = 0;

    for (int i = 2; i <= n; i++) {
        if (isPrime(i)) {
            count++;
        }
    }

    return count;
}

👉 复杂度:O(n√n)


四、高效方法:埃拉托斯特尼筛法(重点🔥)

👉 用于:统计 1 ~ n 所有素数(高性能)

核心思想:

  • 先假设全部是素数
  • 从 2 开始,把倍数全部标记为“非素数”

✅ Java 实现

public static int countPrimes(int n) {
    if (n < 2) return 0;

    boolean[] isPrime = new boolean[n + 1];

    // 初始化:全部设为 true
    for (int i = 2; i <= n; i++) {
        isPrime[i] = true;
    }

    for (int i = 2; i * i <= n; i++) {
        if (isPrime[i]) {
            for (int j = i * i; j <= n; j += i) {
                isPrime[j] = false;
            }
        }
    }

    int count = 0;
    for (int i = 2; i <= n; i++) {
        if (isPrime[i]) count++;
    }

    return count;
}


🚀 优化点(关键理解)

为什么从 i * i 开始?

👉 因为:

i × (i-1) 之前已经被处理过


⏱ 时间复杂度

👉 O(n log log n)(非常快)


五、打印所有素数

public static void printPrimes(int n) {
    boolean[] isPrime = new boolean[n + 1];

    for (int i = 2; i <= n; i++) {
        isPrime[i] = true;
    }

    for (int i = 2; i * i <= n; i++) {
        if (isPrime[i]) {
            for (int j = i * i; j <= n; j += i) {
                isPrime[j] = false;
            }
        }
    }

    for (int i = 2; i <= n; i++) {
        if (isPrime[i]) {
            System.out.print(i + " ");
        }
    }
}


六、完整测试代码(推荐直接运行)

public class PrimeDemo {

    public static boolean isPrime(int n) {
        if (n < 2) return false;

        for (int i = 2; i * i <= n; i++) {
            if (n % i == 0) return false;
        }
        return true;
    }

    public static int countPrimes(int n) {
        boolean[] isPrime = new boolean[n + 1];

        for (int i = 2; i <= n; i++) isPrime[i] = true;

        for (int i = 2; i * i <= n; i++) {
            if (isPrime[i]) {
                for (int j = i * i; j <= n; j += i) {
                    isPrime[j] = false;
                }
            }
        }

        int count = 0;
        for (int i = 2; i <= n; i++) {
            if (isPrime[i]) count++;
        }

        return count;
    }

    public static void main(String[] args) {
        int n = 100;

        System.out.println("100以内素数个数:" + countPrimes(n));

        System.out.print("素数列表:");
        for (int i = 2; i <= n; i++) {
            if (isPrime(i)) {
                System.out.print(i + " ");
            }
        }
    }
}


七、三种方法对比

方法用途时间复杂度推荐
暴力法单个判断O(n)
√n优化单个判断O(√n)⭐⭐⭐⭐
筛法区间统计O(n log log n)⭐⭐⭐⭐⭐

八、进阶优化(精通必备)

⭐ 1. 只判断奇数

减少一半计算


⭐ 2. 线性筛(欧拉筛)

👉 更高级:O(n)


⭐ 3. 大数素性判断

👉 用于密码学(如 RSA)


总结一句话

👉 素数问题核心:

“判断用 √n,统计用筛法”


如果你想继续提升,我可以帮你👇
✅ 出一套「素数算法面试题(含解析)」
✅ 讲清「欧拉筛(线性筛)」
✅ 或带你做「LeetCode 素数专题」

文章已创建 5186

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部