首先了解一下素数
素数:又称质数,有无限个。一个大于1的自然数,除了1和它本身外,不能被其他自然数整除,换句话说就是该数除了1和它本身以外不再有其他的因数;否则称为合数。
如果要找出N以内的所有素数,大家都是这样想的:
#include <stdio.h>
#define N 100
int main()
{
int i,j;
for(i = 2;i <= N;i++)
{
for(j = 2;j < i;j++)
{
if(i % j == 0)
{
break; //找到因数,退出最里面的循环
}
}
if(j == i) //判断因素是不是自己本身
{
printf("%d ",i);
}
}
return 0;
}
像上面这样一个一个数的找过去,再查找因数,如果N是一个本大的数的话,这个耗时将是不可想像的,所以要对以上的算法进行优化一下。
1、缩小查找因素的范围
也就是缩小自变量是 j 的 for 循环,在查找因数的其实可以查找到(平方根+1)就可以了(+1是为了判断有没有整数的平方根,如果没有 j 就会运行到平方根+1,如果有,就会运行j 就会运行到平方根),所以现在可以把 j 的值局限到(平方根+1):
#include <stdio.h>
#include <math.h>
#define N 100
int main()
{
int i,j;
for(i = 2;i <= N;i++)
{
for(j = 2;j < (int)sqrt(i) + 1;j++)
{
if(i % j == 0)
{
break; //找到因数,退出最里面的循环
}
}
if(j == (int)sqrt(i) + 1) //判断因素是不是自己本身
{
printf("%d ",i);
}
}
return 0;
}
相对于一开始的那个方法,这个可以缩短了一段时间,不过当N足够大的时候,这个方法还是不可行的。
2、用数组标记素数
可以先创建一个大小是N + 1的数组,如果是素数就标记对应的值为0,不是素数对应的值就标记为1,等所有数据都判断完了再输出数组中的数据;
#include <stdio.h>
#include <math.h>
#define N 10000
int main()
{
int i,j;
int number[N + 1] = {0}; //是素数就保持为0,是合数就赋值为1
for(i = 2;i <= (int)sqrt(N);i++)
{
if(number[i] == 0) //素数
{
for(j = i * i;j <= N;j += i) //所有i的倍数都不是素数
{
number[j] = 1;
}
}
}
for(i = 2;i <= N;i++)
{
if(number[i] == 0)
{
printf("%d ",i);
}
}
return 0;
}
待补充。。。。。。