素数问题(Prime number problem)的求解 ---- C 语言学习
如果想求 100 以内的全部素数,该怎么办呢?来看看解决方案:
第一种貌似是最直观的,即:若一个数 m 不能被 2 ~ m-1 之间的任何整数整除的话,就表明它是一个素数(Prime Number),程序如下:
#include "stdio.h" void main() { /*求 100 以内的素数*/ int m, n, i, prime; i = 0; for(m = 2; m <= 100; m ++) { prime = 1;/*设定一个标志,先假定是素数*/ for(n = 2; n < m; n ++) if(m % n == 0) prime = 0;/*表明 m 不是素数*/ if(prime)/*是素数*/ { printf("%6d", m); i ++; if(i % 5 == 0) printf("\n"); } } if(i % 5 != 0) printf("\n"); }
运行结果:
第二种采用筛选法来求素数:
使用筛选法求素数的基本思想是:把某一范围内的正整数按从小到大的顺序排列,宣布 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
首先宣布 2 是素数,然后去掉它的倍数:
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 - - - - -
余下的数是:
3 5 7 9 11 13 15 17 19 21 23 25 27 29
宣布最小的数 3 是素数,并去掉它的倍数:
3 5 7 9 11 13 15 17 19 21 23 25 27 29 - - - - -
如此下去,直到所有的数都被筛完,宣布的素数有:
2 3 5 7 11 13 17 19 23 29
算法思路:写程序的时候,采用一个数组,用数组的下标来表示自然数,如果一个数不在筛子中就将其对应的元素赋值为 0 ,如果仍旧在筛子中,则那个元素的值为 1。来看看程序:
#include "stdio.h" #define RANGE 200 void main() { char sieve[RANGE + 1]; int i, j, count; for(i = 0; i <= RANGE; i ++) sieve[i] = 1;/*初始化*/ sieve[0] = sieve[1] = 0;/*0 和 1 不是素数*/ count = 0; for(i = 2; i <= RANGE; i ++) if(sieve[i] == 1)/*i 是素数*/ { printf("%5d", i);/*输出素数*/ count ++; if(count % 8 == 0)/*每行输出 8 个值*/ printf("\n"); for(j = i; j <= RANGE; j += i) sieve[j] = 0;/*筛去 i 的倍数*/ } printf("\n"); }
来看看运行结果: