生成素数有很多方法,本文介绍的算法是一种高效的筛选算法 ---埃拉托色尼筛选法。算法思想很简洁,比如,要产生[2,n] 范围内的所有素数,步骤如下:
1、构造一个2,3,4,5,...n 的候选数序列 A 。
2、不断的去除(筛掉)序列A中的非素数。
①去掉2的倍数。
②再去掉3的倍数。
③去掉4的倍数(不需要,因为在第一步已经被去掉了)
去掉5的倍数。
④去掉6的倍数
⑤去掉7 的倍数
... ...一直到不能再去除为止。
实现的时候,其他代码都很容易懂,但这句for(j=i*i; j<MAX; j+=i)notirime[j]=true你可能会产生疑问。为什么是从i*i开始呢,为什么不去除 2*i ,3*i,4*i ...i(i-1)呢?不是应该除i 的所有倍数的吗?
解答:对于一个数i,会依次去除 i*i , i(i+1), i(i+2) .... i(i+k) (i(i+k)<=n),不从2*i开始去除,那是因为在去除i的倍数之前,我们已经去除了 i-1 , i-2 ,i-3 ... 4 , 3 , 2 的这些数的倍数,所以 , i(i-1) , i(i-2) .... i*3,i*2在之前的操作中被去除了。
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define MAX 10000000
bool notprime[MAX];
int prime[MAX];
void init()
{
memset(notprime,false,sizeof(notprime));
notprime[0]=notprime[1]=true;
int i,j;
for(i=2; i*i<MAX; ++i)
{
if(!notprime[i])
{
for(j=i*i; j<MAX; j+=i)
{
notprime[j]=true;
}
}
}
int num=0;
for(i=2; i<MAX; ++i)
if(!notprime[i])
{
prime[num++]=i;
}
}
int main()
{
int i,j,k;
init();
for(i=0; i<100; i++)
{
printf("%d ",prime[i]);
if(i==50)printf("\n");
}
return 0;
}