基礎知識儲備-快速篩法求素數

普通的線性篩法:


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]);
		}
	}

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章