普通的线性筛法:
public class Main {
static int N=1001;
static int []prime=new int [N+1];
static int []su=new int [N+1];
static int cnt;
static boolean []isprime =new boolean[N+1];
public static void prime() {
cnt=1;
for(int i=2;i<=N;i++) {
if(!isprime[i]) { //保存素数
su[cnt++]=i;
}
for(int j=2*i;j<=N;j+=i) { //素数的倍数都为合数
isprime[j]=true;
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
prime();
for(int i=1;i<cnt;i++) {
System.out.println(su[i]);
}
}
}
普通的线性筛法虽然大大缩短了求素数的时间,但是实际上还是做了许多重复运算,比如2*3=6,在素数2的时候筛选了一遍,在素数为3时又筛选了一遍。如果只筛选小于等于素数i的素数与i的乘积,既不会造成重复筛选,又不会遗漏。时间复杂度几乎是线性的。
优化后的线性筛法:
public class Main {
static int N=1001;
static int []prime=new int [N+1];
static int []su=new int [N+1];
static int cnt;
static boolean []isprime =new boolean[N+1];
public static void prime() {
cnt=1;
for(int i=2;i<=N;i++) {
if(!isprime[i]) {
su[cnt++]=i;
}
for(int j=1;j<=cnt&&su[j]*i<N;j++) {
isprime[su[j]*i]=true; //筛掉小于等于i的素数和i的积构成的合数
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
prime();
for(int i=1;i<cnt;i++) {
System.out.println(su[i]);
}
}
}