轉載:http://blog.csdn.net/liukehua123/article/details/5482854
判斷一個數字是否為素數,正如大家都知道的那樣,一個數 n 如果是合數,那么它的所有的因子不超過sqrt(n)--n的開方,那么我們可以用這個性質用最直觀的方法
來求出小於等於n的所有的素數。
num = 0;
for(i=2; i<=n; i++)
{ for(j=2; j<=sqrt(i); j++)
if( j%i==0 ) break;
if( j>sqrt(i) ) prime[num++] = i; //這個prime[]是int型,跟下面講的不同。
}
這就是最一般的求解n以內素數的算法。復雜度是o(n*sqrt(n)),如果n很小的話,這種算法(其實這是不是算法我都懷疑,沒有水平。當然沒
接觸過程序競賽之前我也只會這一種求n以內素數的方法。-_-~)不會耗時很多.
但是當n很大的時候,比如n=10000000時,n*sqrt(n)>30000000000,數量級相當大。在一般的機子它不是一秒鍾跑不出結果,它是好幾分鍾都跑不
出結果,這可不是我瞎掰的,想鍛煉耐心的同學不妨試一試~。。。。
在程序設計競賽中就必須要設計出一種更好的算法要求能在幾秒鍾甚至一秒鍾之內找出n以內的所有素數。於是就有了素數篩法。
(我表達得不清楚的話不要罵我,見到我的時候扁我一頓我不說一句話。。。)
素數篩法是這樣的:
1.開一個大的bool型數組prime[],大小就是n+1就可以了.先把所有的下標為奇數的標為true,下標為偶數的標為false.
2.然后:
for( i=3; i<=sqrt(n); i+=2 )
{ if(prime[i])
for( j=i+i; j<=n; j+=i ) prime[j]=false;
}
3.最后輸出bool數組中的值為true的單元的下標,就是所求的n以內的素數了。
原理很簡單,就是當i是質(素)數的時候,i的所有的倍數必然是合數。如果i已經被判斷不是質數了,那么再找到i后面的質數來把這個質
數的倍數篩掉。
一個簡單的篩素數的過程:n=30。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
第 1 步過后2 4 ... 28 30這15個單元被標成false,其余為true。
第 2 步開始:
i=3; 由於prime[3]=true, 把prime[6], [9], [12], [15], [18], [21], [24], [27], [30]標為false.
i=4; 由於prime[4]=false,不在繼續篩法步驟。
i=5; 由於prime[5]=true, 把prime[10],[15],[20],[25],[30]標為false.
i=6>sqrt(30)算法結束。
第 3 步把prime[]值為true的下標輸出來:
for(i=2; i<=30; i++)
if(prime[i]) printf("%d ",i);
結果是 2 3 5 7 11 13 17 19 23 29