素數篩選法,快速獲取素數序列
阿新 • • 發佈:2019-01-01
今天,學習了素數求取的方法,感覺很棒,拿來分享一下。首先,對比一下兩種方法:普通求取素數的方法和基於篩選法的素數求取方法。
-普通方法求取素數
普通方法求取素數是根據素數的定義來判斷一個數N是否為素數(只有1和它本身能夠整除自己)。因此,該方法一般方式是測試1到的N所有數是否整除N,來判斷N是否為素數的。程式碼示例如下:
#include<stdio.h>
#include<math.h>
#define N 10000001
int prime[N];
int main()
{
int i, j, 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;
}
for(i=2; i<100; i++) //只輸出2-100內的素數
if( prime[i] )printf("%d ",i);
return 0;
}
這段程式碼在我的1G記憶體,單核CPU的雲主機上,會執行相當長的時間。
-基於篩選法的素數求取方式
基於篩選法的素數求取方式:用陣列的方式存取篩選候選集,根據質數的倍數不是質數,偶數不是質數的原則進行一次次篩選。但是,不知道為什麼for迴圈的結束位置是sqrt(N
#include <stdio.h>
#include <math.h>
#define N 10000001
int prime[N];
int main()
{
int i, j;
for(i=2; i<N; i++){
if(i%2) prime[i]=1;
else prime[i]=0;
}
for(i=3; i<=sqrt(N); i++)
{ if(prime[i]==1)
for(j=i+i; j<N; j+=i) prime[j]=0;
}
for (i=2; i<100; i++)//只輸出2-100內的素數
if( prime[i]==1 )printf("%d ",i);
printf("\n");
return 0;
}
基於篩選法的素數求取方式,執行時間短。一部分原因是時間複雜度小,一部分原因是省去了CPU開根號佔用的時間。綜上,基於篩選法的素數求取方式是一個快速、實用的求取素數的方法。
另外,還可以針對基於篩選法的素數求取方式做進一步的優化。簡化陣列的佔用空間:因為所有的偶數都不是質數(除2之外),所以陣列可以只存放奇數,省掉一半的佔用空間。