Java中采用埃拉托斯特尼筛法计算质数
埃拉托斯特尼筛法(Sieve of Eratosthenes)是一种高效求解一定范围内所有质数的经典算法,由古希腊数学家埃拉托斯特尼提出。它的核心思想是:从最小的质数开始,把它的所有倍数全部筛掉,剩下的就是质数。
一、基本概念
-
质数:也叫素数,是指大于 1 且只能被 1 和自身整除的整数
-
目标:找出区间 [2,n] 内的所有质数
二、算法思想
-
创建一个长度为 n+1 的布尔数组
isPrime -
初始时,假设 2 到 n 全部是质数
-
从最小的质数 2 开始:
-
把 2 的倍数(4, 6, 8, …)全部标记为非质数
-
-
找到下一个仍未被标记的数(如 3):
-
把 3 的倍数(6, 9, 12, …)全部标记为非质数
-
-
重复以上过程
-
最终所有没被标记的数就是质数
三、算法步骤
-
创建数组
isPrime[0..n] -
将
isPrime[0]和isPrime[1]设为false -
其余设为
true -
对
i从 2 到 √n:-
若
isPrime[i] == true-
对
j从i*i到n,步长为i-
isPrime[j] = false
-
-
-
-
遍历数组,输出所有
isPrime[i] == true的i
四、代码部分
传统写法:
1 // 传统写法 2 public static void calPrimeByNormal(int num){ 3 System.out.println("正在普通法查找 " + num + " 以内的素数..."); 4 int count = 0; 5 for (int i = 2; i <= num; i++) { 6 boolean flag = true; 7 for (int j = 2; j < i; j++) { 8 if (i % j == 0) { 9 flag = false; 10 break; 11 } 12 } 13 if (flag) { 14 count++; 15 } 16 } 17 System.out.println(num + "以内的素数有" + count + "个"); 18 }
采用埃拉托斯特尼筛法写法:
1 // 优化写法 采用埃拉托斯特尼筛法 2 public static void calPrimeBySieve(int num){ 3 System.out.println("正在以埃拉托斯特尼筛法查找 " + num + " 以内的素数..."); 4 boolean[] isPrime = new boolean[num+1]; 5 Arrays.fill(isPrime, true); 6 isPrime[0] = isPrime[1] = false; 7 for (int i = 2; i < Math.sqrt(num); i++) { 8 if (isPrime[i]) 9 for (int j = i*i; j <= num; j += i) 10 isPrime[j] = false; 11 } 12 int count = 0; 13 for (boolean k : isPrime) { 14 if (k) 15 count++; 16 } 17 System.out.println(num + "以内的素数有" + count + "个"); 18 }
测试查找100000以内的质数速度对比:
1 public static void main(String[] args) { 2 int num = 100000; 3 long startTime = System.currentTimeMillis(); 4 calPrimeByNormal(num); 5 long endTime = System.currentTimeMillis(); 6 System.out.println("普通法查找程序运行时间:" + (endTime - startTime) + "ms"); 7 System.out.println(); 8 startTime = System.currentTimeMillis(); 9 calPrimeBySieve(num); 10 endTime = System.currentTimeMillis(); 11 System.out.println("埃拉托斯特尼筛法查找程序运行时间:" + (endTime - startTime) + "ms"); 12 }
输出结果:
正在普通法查找 100000 以内的素数... 100000以内的素数有9592个 普通法查找程序运行时间:623ms 正在以埃拉托斯特尼筛法查找 100000 以内的素数... 100000以内的素数有9592个 埃拉托斯特尼筛法查找程序运行时间:3ms
测试查找1000000以内的质数速度对比输出结果:
正在普通法查找 1000000 以内的素数... 1000000以内的素数有78498个 普通法查找程序运行时间:51197ms 正在以埃拉托斯特尼筛法查找 1000000 以内的素数... 1000000以内的素数有78498个 埃拉托斯特尼筛法查找程序运行时间:20ms
可见,查找速度提升很明显。
五、为什么外层循环只筛到 √n?
-
若 x=a×b,,且 x ≤ n
-
那么至少有一个因子满足 a ≤ √n
-
所以:
-
如果一个数在 √n 之前没被筛掉
-
那么它一定是质数
-
因此,外层循环只需要进行到 √n。
六、为什么从 i² 开始筛?
以当前质数 i 为例:
-
小于 i^2 的倍数:
-
2i,3i,4i,…
-
-
这些数在之前:
-
已经被更小的质数筛掉了
(如 3×5=15,会在筛 3 时被处理)
-
所以:
-
从 i^2 开始筛既正确又高效

浙公网安备 33010602011771号