算法:素數的篩法

一 寫在開頭

1.1 本文內容

本文實現了素數的篩法算法。算法

 

二 算法原理與實現

在寫代碼的過程當中,時不時會遇到求解素數的任務,特地將素數求解方法總結成文章以備不時之需。素數的求解算法大概有兩種。一種是枚舉某一範圍的數,而後逐個判斷該數是否爲素數。這種方法簡單但效率不高。另外一種方法是使用素數的篩法將某一範圍內的全部素數篩選出來,而後再打表。篩法的原理很簡單:從最小的素數2開始,依次將2的倍數給剔除,而後將後面沒有被剔除的最小素數3的倍數依次剔除......重複上述操做就能夠將範圍內的全部合數給剔除掉,剩下的天然就是素數。該算法能夠使用C語言實現,以下面的代碼所示。數組

 1 #include <string.h>
 2 
 3 /* 使用0和-1是爲了使用內存填充函數memset */
 4 #define FALSE           (-1)
 5 #define TRUE            0
 6 #define MAX_RANGE_N     10000
 7 
 8 unsigned int counter = 0;  9 static char indexs[MAX_RANGE_N]; 10 static int primes[MAX_RANGE_N]; 11 
12 void ScreenPrimes(char *indexs, int *primes, unsigned int *counter) 13 { 14     int i, j, k; 15 
16     /* 數組名作函數參數將退化成指針,所以須要乘於MAX_RANGE_N */
17     memset(indexs, TRUE, sizeof(indexs[0]) * MAX_RANGE_N); 18     indexs[0] = indexs[1] = FALSE; 19 
20     /* 篩選過程 */
21     for (i = 2; i < MAX_RANGE_N; i++) 22         if (indexs[i] == TRUE) 23             for (j = i + i; j < MAX_RANGE_N; j += i) 24                 indexs[j] = FALSE; 25 
26     /* 拷貝過程,其中k值表示範圍內素數的個數 */
27     k = 0; 28     for (i = 0; i < MAX_RANGE_N; i++) 29         if (indexs[i] == TRUE) 30             primes[k++] = i; 31     *counter = k; 32 }

值得注意的是在memset函數中,sizeof(indexs[0])返回一個unsigned int值,若是MAX_RANGE_N很大的話,其和MAX_RANGE_N相乘會有溢出的危險。函數

 

有了上述的實現,要求打印前50個素數能夠用下述代碼實現。spa

 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 /* 使用0和-1是爲了使用內存填充函數memset */
 5 #define FALSE           (-1)
 6 #define TRUE            0
 7 #define MAX_RANGE_N     10000
 8 
 9 unsigned int counter = 0; 10 static char indexs[MAX_RANGE_N]; 11 static int primes[MAX_RANGE_N]; 12 
13 void ScreenPrimes(char *indexs, int *primes, unsigned int *counter) 14 { 15     int i, j, k; 16 
17     /* 數組名作函數參數將退化成指針,所以須要乘於MAX_RANGE_N */
18     memset(indexs, TRUE, sizeof(indexs[0]) * MAX_RANGE_N); 19     indexs[0] = indexs[1] = FALSE; 20 
21     /* 篩選過程 */
22     for (i = 2; i < MAX_RANGE_N; i++) 23         if (indexs[i] == TRUE) 24             for (j = i + i; j < MAX_RANGE_N; j += i) 25                 indexs[j] = FALSE; 26 
27     /* 拷貝過程,其中k值表示範圍內素數的個數 */
28     k = 0; 29     for (i = 0; i < MAX_RANGE_N; i++) 30         if (indexs[i] == TRUE) 31             primes[k++] = i; 32     *counter = k; 33 } 34 
35 int main() 36 { 37     int i; 38 
39     ScreenPrimes(indexs, primes, &counter); 40     for (i = 0; i < 50; i++) 41         printf("%d ", primes[i]); 42     putchar('\n'); 43 
44     return 0; 45 }
相關文章
相關標籤/搜索