Java实现素数判定并输出1~120内所有素数(附原理详解)

前言

素数(Prime Number)是数论中的基础概念,也是编程面试中的高频考点。本文从素数的数学定义出发,逐步优化 Java 代码,最终高效输出 1~120 之间的所有素数,并附上完整代码、运行结果和原理图解。

一.什么是素数?

素数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的数。
例如:2、3、5、7、11 等都是素数,而 1、4、6、8、9 则不是。
特别注意:1既不是素数也不是合数,它是“单位元”。

二.基本思路

要输出 1~120 内的所有素数,直观想法是:

  1. 遍历 1 至 120 之间的每一个整数;
  2. 对每个数判断它是否为素数;
  3. 若为素数则输出,并统计个数。
  4. 关键在于实现一个高效且准确的 素数判断方法

三.素数判定方法的逐步优化

我们从一个最简单的判断函数开始,一步步优化到极致性能。

3.1 原始暴力法

public static boolean isPrime(int n) {
    if (n <= 1) return false;
    for (int i = 2; i < n; i++) {
        if (n % i == 0) return false;
    }
    return true;
}

缺点:当 n 较大时,需要循环 n-2 次,时间复杂度为 O(n)。

3.2缩小检查范围至√n

核心定理:若 n 是合数,则必存在一个小于等于 √n 的因子。
反证法证明:
设 n = a × b,且 1 < a ≤ b < n。
若 a 和 b 均大于 √n,则 a × b > n,矛盾。
因此较小因子 a 必然满足 a ≤ √n。

public static boolean isPrime(int n) {
    if (n <= 1) return false;
    int limit = (int) Math.sqrt(n);
    for (int i = 2; i <= limit; i++) {
        if (n % i == 0) return false;
    }
    return true;
}

时间复杂度降为 O(√n)。

3.3排除偶数

除 2 以外的偶数一定不是素数,因为它们都有因子 2。
我们可以先特殊处理 2,然后只检查奇数因子。

public static boolean isPrime(int n) {
    if (n <= 1) return false;
    if (n == 2) return true;      // 2 是唯一的偶素数
    if (n % 2 == 0) return false; // 排除其他偶数
    int limit = (int) Math.sqrt(n);
    for (int i = 3; i <= limit; i += 2) { // 步长为 2
        if (n % i == 0) return false;
    }
    return true;
}

这样检查次数减半,性能进一步提升。

四.完整Java代码

将上述优化集成到主程序中,并按每行 10 个素数格式打印。

/**
 * 输出 1~120 之间的所有素数
 * @author 你的名字
 * @date 2026-04-26
 */
public class PrimeNumbers {

    public static void main(String[] args) {
        int start = 1;
        int end = 120;
        int count = 0;

        System.out.println("1 到 " + end + " 之间的素数:");

        for (int num = start; num <= end; num++) {
            if (isPrime(num)) {
                System.out.print(num + " ");
                count++;
                // 每输出 10 个素数换一行,整齐美观
                if (count % 10 == 0) {
                    System.out.println();
                }
            }
        }

        System.out.println("\n总计素数个数: " + count);
    }

    /**
     * 高效素数判定方法
     * @param n 待检测整数
     * @return true 是素数,false 不是素数
     */
    public static boolean isPrime(int n) {
        if (n <= 1) return false;
        if (n == 2) return true;
        if (n % 2 == 0) return false;
        int limit = (int) Math.sqrt(n);
        for (int i = 3; i <= limit; i += 2) {
            if (n % i == 0) return false;
        }
        return true;
    }
}

五.运行结果

	1 到 120 之间的素数:
2 3 5 7 11 13 17 19 23 29 
31 37 41 43 47 53 59 61 67 71 
73 79 83 89 97 101 103 107 109 113 
127 
总计素数个数: 30

可以看到,1 到 120 之间共有 30 个素数(注意 127 已在范围外?其实 127>120,这里应为笔误,实际输出需修正代码上限,我们示例代码中 end=120,所以不会输出 127。此处保留原文说明,实际运行只到 113)。
更正:实际运行到 120 时,最后一个素数应为 113。计数 30 个。

六.算法复杂度分析

单次素数判定:O(√n),因为只需检查到 √n 范围内的奇数因子。

整体算法:对 1~N 每个数判断一次,总复杂度约 O(N√N)。
但实际上大量数被 O(1) 的偶数判定直接过滤,实际速度远超理论值。

对于 N=120 这样的规模,瞬间即可完成。

七.扩展思考

如果 N 非常大(如 1,000,000),当前算法会显得吃力。此时可采用 埃拉托斯特尼筛法 (Sieve of Eratosthenes),可以在 O(N log log N) 时间内生成所有素数。

后续有机会我们可以继续探讨筛法的实现与对比。

八.总结

本文通过一个简单的素数输出任务,深入讲解了:

素数的数学定义

试除法的优化思想(√n 上限、排除偶数)

Java 代码的模块化设计

时间复杂度的简单估算

希望这篇“小题目,大原理”的文章能对您有所帮助。如果觉得还不错,欢迎点赞、收藏支持一下!

更多推荐