素数(质数):除了1和它本身外不存在其他因子。1不是质数
时间复杂度:nlogn
- 假设要寻找 1——maxn 中的素数,首先定义一个数组来标记,prime[i]=true 表示i是质数,刚开始还未寻找质数,所以把
2——maxn 都标记为true
bool prime[maxn];
for(int i=2;i<=maxn;++i) prime[i]=true;
- 然后从2开始,一个一个筛查prime[i],当其为真时 ,就把i放进统计素数的数组 z[ ],素数总数tot+1 与此同时——
- 重点: 因为任何一个合数可以表示为数个质数的乘积,我们用其中最小的质数筛掉这个合数
利用已经统计到的素数数组 z[ ] 把以i为因子的合数标记为false(这样保证了每一个数只被筛一次)
for(int j=0;j<tot && i*p[j]<maxn; ++j)
{
prime[i*z[j]]=false;
if(i%z[j]==0) break;
}
}
板子
#include<cstdio>
#include<iostream>
using namespace std;
const int maxn=10000; //maxn表示要筛选素数的最大值
bool prime[maxn+10];
int z[maxn+10],tot; //z[]记录查找到的素数,tot查找到的素数总数,
void init()
{
for(int i=2;i<=maxn;++i) prime[i]=true; //初始化标记
for(int i=2;i<=maxn;++i)
{
if(prime[i]) z[tot++]=i; //存储质数
for(int j=0;j<tot && i*z[j]<maxn; ++j) //利用最小的质数因子筛去合数
{
prime[i*z[j]]=false;
if(i%z[j]==0) break; //保证了每个合数数是被最小的质数因子筛去,避免重复筛减
}
}
}
int main()
{
init();
}