判断一个数是否为质数/合数是在数据处理中经常遇到的问题,如何解决这个问题,作者总结了如下几种算法。
质数的定义:
一个数如果除了1 和 其本身外,不能被其它数整除,就称这个数为质数(或素数)。
合数的定义:
一个数除了1和其本身外,还可以被其它数整除,那么就称这个数为合数。
- 第一种:枚举法
这个方法的思想就是利用质数的定义来进行枚举判定。例如,判断数字N是否为质数,那么就逐一判断2~N-1 范围内的每一个数,是否可以被N整除,只要在这个范围内存在任意一个可以被N整除的数,就称N 为非质数。
//代码段1
//10000内的所有质数的个数
#include <stdio.h>
#define MAX_N 10000
int is_prime(int n){
for(int i = 2;i < n-1;i++){
if(n % i == 0) return 0;
}
return 1;
}
int main(){
int count = 0;
for(int i = 2;i <= MAX_N;i++){
if(is_prime(i)) ++count ;
}
printf("num is %d\n",count);
return 0;
}
运行结果:
在10000以内,存在1229个质数,运行这段枚举代码用了0.21秒。
枚举法分析:
优点:通过定义去判断,代码实现思路易于理解;
缺点:如果数据范围较大,即N值较大,在2~N-1 范围内逐一枚举,判断枚举值是否可以被N值整除,效率较低;
- 第二种 优化枚举法
第一种方法的缺点显而易见,在进行枚举判断时的枚举范围是2~N-1, 缩小枚举范围就是优化方向。
我们知道,如果一个数N是合数,那么一定存在这样的关系:N = a*b (a和b 均不等于1 或者N本身) ,且因为存在 N = *
;所以,a 一定大于或等于
, 而b一定小于或等于
,不存在a和b同时大于或同时小于
的情况。因此,枚举范围可以修改为2~
, 因为,如果N是合数,那么在这个范围内必然存在一个它的因子。
//代码段2
/