埃拉托斯特尼筛法
埃拉托斯特尼筛法(Sieve of Eratosthenes)是一种用于找出一定范围内所有质数的经典算法。它的基本思想是从小到大依次筛选掉合数(非质数),最终剩下的就是质数。以下是详细的步骤说明:
- 创建一个布尔数组
isPrime
,用于表示每个数字是否为质数。初始化时,将所有数字标记为质数(初始化为true
)。 - 根据质数的定义,从 2 开始,将其标记为质数,然后将它的倍数标记为非质数。因为 0 和 1 不是质数,所以我们从 2 开始。
- 对于当前的质数
p
,从p * p
开始,将其所有小于等于n
的倍数标记为非质数。这是因为任何小于p * p
的倍数已经在之前的质数中被标记过了。例如,当p
为 2 时,我们从 4 开始标记,因为 2 * 2 = 4。而当p
为 3 时,我们从 9 开始标记,因为 3 * 3 = 9。 - 重复步骤 3,直到
p * p > n
。 - 最后,遍历布尔数组
isPrime
,将所有标记为质数的数字提取出来,形成质数列表。
这个算法的核心思想是,每次找到一个质数,就将其所有的倍数标记为非质数,这样逐步排除了所有的合数,只剩下质数。这种方法避免了重复的除法运算,因此在一定范围内查找质数非常高效。
埃拉托斯特尼筛法的时间复杂度是 O(n log log n),其中 n
是要查找的质数的上限。这使得它成为找出相对较小范围内的质数的一种有效方法。
import java.util.ArrayList;
import java.util.List;
public class PrimeSieve {
public static List<Integer> findPrimes(int n) {
// 创建一个布尔数组来标记每个数字是否为质数
boolean[] isPrime = new boolean[n + 1];
for (int i = 0; i <= n; i++) {
isPrime[i] = true; // 先默认所有数字都是质数
}
isPrime[0] = isPrime[1] = false; // 0 和 1 不是质数
// 使用埃拉托斯特尼筛法来标记非质数
for (int num = 2; num * num <= n; num++) {
if (isPrime[num]) {
for (int multiple = num * num; multiple <= n; multiple += num) {
isPrime[multiple] = false; // 将num的倍数标记为非质数
}
}
}
// 将标记为质数的数字放入一个列表中
List<Integer> primes = new ArrayList<>();
for (int i = 2; i <= n; i++) {
if (isPrime[i]) {
primes.add(i);
}
}
return primes;
}
public static void main(String[] args) {
List<Integer> primesInRange = findPrimes(10000);
System.out.println(primesInRange);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
编辑 (opens new window)
上次更新: 2024/02/22, 14:03:19