1. 程式人生 > >素數篩選法,快速獲取素數序列

素數篩選法,快速獲取素數序列

今天,學習了素數求取的方法,感覺很棒,拿來分享一下。首先,對比一下兩種方法:普通求取素數的方法和基於篩選法的素數求取方法。

-普通方法求取素數

普通方法求取素數是根據素數的定義來判斷一個數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之外),所以陣列可以只存放奇數,省掉一半的佔用空間。