素数筛:埃氏筛法 Java版本
一、引言
素数是数学中一个重要的概念,它指的是只能被1和自身整除的大于1的自然数。在计算机科学中,素数的筛选是一个常见的问题,尤其是在加密算法和数论研究中。埃拉托斯特尼筛法(简称埃氏筛法)是一种高效的素数筛选算法,能够快速找出一定范围内的所有素数。本文将介绍埃氏筛法的基本原理及其Java实现。
二、算法原理
1、基本原理
埃氏筛法的基本思想是:从最小的素数2开始,逐步将每个素数的倍数标记为合数(非素数)。具体步骤如下:
1.1、初始化
- 创建一个布尔数组
isPrime
,长度为n+1
,其中n
是要筛选的范围上限。数组的索引表示自然数,初始时将所有元素设为true
,表示假设所有数都是素数。 - 将索引为0和1的元素设为
false
,因为0和1不是素数。
1.2、筛选过程
- 从2开始,遍历数组中的每个数
p
。 - 如果
isPrime[p]
为true
,则p
是素数,将其所有倍数p*p, p*(p+1), p*(p+2), ...
标记为false
。 - 重复上述步骤,直到遍历完所有小于等于
sqrt(n)
的数。
2、优化策略
- 只需遍历到
sqrt(n)
,因为大于sqrt(n)
的素数倍数已经被小于sqrt(n)
的素数倍数覆盖。 - 从
p*p
开始标记倍数,因为p*2, p*3, ...
等倍数在之前的步骤中已经被标记过了。
三、Java实现
以下是埃氏筛法的Java代码实现:
import java.util.Scanner;
public class SieveOfEratosthenes {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
boolean[] isPrime = new boolean[n + 1];
// 初始化数组
for (int i = 2; i <= n; i++) {
isPrime[i] = true;
}
// 筛选过程
for (int p = 2; p * p <= n; p++) {
if (isPrime[p]) {
for (int i = p * p; i <= n; i += p) {
isPrime[i] = false;
}
}
}
// 输出素数
for (int i = 2; i <= n; i++) {
if (isPrime[i]) {
System.out.println(i);
}
}
}
}
四、使用示例
使用埃氏筛法求取2~100以内素数的Java代码示例:
public class PrimeSieve {
public static void main(String[] args) {
int limit = 100; // 定义范围上限
boolean[] primes = new boolean[limit + 1]; // 创建布尔数组,primes[i]表示i是否为素数
// 初始化:将所有数标记为素数
for (int i = 2; i <= limit; i++) {
primes[i] = true;
}
// 根据埃氏筛法剔除非素数
for (int i = 2; i * i <= limit; i++) { // 只需检查到√limit即可
if (primes[i]) { // 如果i是素数
for (int j = i * i; j <= limit; j += i) { // 去掉i的所有倍数
primes[j] = false; // 将它们标记为非素数
}
}
}
// 输出2-100之间的素数
System.out.println("2-100之间的素数:");
for (int i = 2; i <= limit; i++) {
if (primes[i]) {
System.out.print(i + " ");
}
}
}
}
运行这段代码,你会得到2到100之间的所有素数。
五、总结
埃氏筛法是一种简单而高效的素数筛选算法,适用于快速找出一定范围内的所有素数。通过Java语言的实现,我们可以轻松地应用这一算法来解决实际问题。本文提供了基本的实现方法和优化策略,帮助读者更好地理解和运用埃氏筛法。
版权声明:本博客内容为原创,转载请保留原文链接及作者信息。
参考文章: