華爲一道筆試題:打印2~2000的所有素數,要求儘量快

傳統算法:

逐個判斷是不是素數,有的簡單優化就是在判斷的時候使用的上限是平方根,當然每個數字還是要逐個判斷,使用的是i++的形式

這裏使用的是篩法:

並不是逐個判斷,篩法的定義爲:

先把N個自然數按次序排列起來。1不是質數,也不是合數,要劃去。第二個數2是質數留下來,
而把2後面所有能被2整除的數都劃去。2後面第一個沒劃去的數是3,把3留下,再把3後面所有能被3整除的數都劃去。
3後面第一個沒劃去的數是5,把5留下,再把5後面所有能被5整除的數都劃去。
c這樣一直做下去,就會把不超過N的全部合數都篩掉,留下的就是不超過N的全部質數。因爲希臘人是把數寫在塗臘的板上,
每要劃去一個數,就在上面記以小點,尋求質數的工作完畢後,這許多小點就像一個篩子,
所以就把埃拉託斯特尼的方法叫做“埃拉託斯特尼篩法”,簡稱“篩法”。
(另一種解釋是當時的數寫在紙草上,每要劃去一個數,就把這個數挖去,尋求質數的工作完畢後,這許多小洞就像一個篩子。

並不逐個判斷:首先:偶數一定不是素數,所以我循環的時候採用的不是i++,而是i每次加2,判斷是否是素數的似乎也不是將2到本身(或是平方根)的逐個相除看是否能夠除盡來運算,而是篩選法的方式,每個數因爲在循環的時候就確定了一定是基數,所以判斷只需要是小於它的基數,而不是逐個,當然也就可以改良爲小於它平方根來判斷。不知道是不是最優,如果有更好的方法,希望能貼出來吧sincerely...

summary:判斷是否是素數的時候上限,使用的是平方根或者是本身對於效率改進並不會有太大改進。因爲:平方根屬於底層封裝,並不能很快得到結果。而簡單的循環則是速度極快的,相比循環次數增加但是計算平方根的時間增加,所以其實效率不會有太大的改善

代碼:

package algorithm;
/**
 * 2~2000的所有素數,要求效率儘可能高
 * @author cilen
 *
 */
public class PrimeTest {
public static void main(String[] args) {
	long t = System.currentTimeMillis();
	int  count=1;
	System.out.println(2);//2是已知不需要參與判斷
	for(int i=3;i<2000;)
	{
		if(isPrime(i))
		{
			count++;
			System.out.println(i);
		}
		i=i+2;//每次加2,不是加1
	}
	System.out.println("總共的個數爲:"+count);
	t = System.currentTimeMillis()-t;
	System.out.println("經歷的時間爲:"+t);
}


public  static boolean isPrime(int n )
{
	for(int j=3;j<n;)
//int max=(int)Math.floor(Math.sqrt(n));下面的Math.sqrt(n)可以被替換爲這個max
 //		for(int j=3;j<=Math.sqrt(n);)--這裏是<=,如果少了等於,會出現能開平方根的數被打印
	{
		if(n%j==0)
		{
			 return false;
		}
		j=j+2;
	}
	return true;
}
}

具體哪個是素數就不打印了
總共的個數爲:303
經歷的時間爲:13
傳統的方法:

package algorithm;

public class Demo {
	public static void main(String[] args)
	{
			long t = System.currentTimeMillis();
		int 	count =0;
			int i,j,k=0; 
			for(i=2;i<=2000;i++)
			{   
			for(j=2;j<=i/2;j++)   
			if(i%j==0)break;   
			if(j>i/2)   
					
				{ 
				System.out.println(i);
				count++;
				}   
			}
			t = System.currentTimeMillis()-t;
		System.out.println("總共個數:"+count);
		System.out.println("經歷的時間爲:"+t);
	}

}

得出:

總共個數:303
經歷的時間爲:19

可見:使用篩選法的時間能節省約:1/3

希望得到更好的算法或者改進,待mark...


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