普通的線性篩法:
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]);
}
}
}