本文實現了素數的篩法算法。算法
在寫代碼的過程當中,時不時會遇到求解素數的任務,特地將素數求解方法總結成文章以備不時之需。素數的求解算法大概有兩種。一種是枚舉某一範圍的數,而後逐個判斷該數是否爲素數。這種方法簡單但效率不高。另外一種方法是使用素數的篩法將某一範圍內的全部素數篩選出來,而後再打表。篩法的原理很簡單:從最小的素數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 }