快速线性素数筛法(欧拉筛法),时间复杂度O(n)。
诀窍在于:筛除合数时,保证每个合数只会被它的最小质因数筛去。因此每个数只会被标记一次,所以算法时间复杂度为O(n)。
具体请看下面的代码,主要函数是Prime(n)。
#include<bits/stdc++.h>
using namespace std;
vector <int>Prime(int n)
{
// 标记数组,flag[i]==0表示i为素数,flag[i]==1表示i为合数
bool flag[n+1];
memset(flag,0,sizeof(flag));
vector<int>prime;
int cnt=0;//素数个数
for(int i=2;i<n;i++)
{
if(!flag[i])
{
//cout<<i<<endl;
prime.push_back(i);//将i加入素数表
cnt++;
}
//将每个素数的倍数都筛去
for(int j=0;j<cnt;j++)
{
if(i*prime[j]>n) break;
flag[i*prime[j]]=1;
//cout<<i*prime[j]<<endl;
// 保证每个合数只会被它的最小质因数筛去
if(i%prime[j]==0) break;
}
}
return prime;
}
int main()
{
int n;
while(1)
{
cout<<"请输入n,将输出n以内(含n)的素数:"<<endl;
cin>>n;
vector<int> prime = Prime(n);
int cnt=prime.size();
cout<<"一共有"<<cnt<<"个素数:"<<endl;
for(int i=0;i<cnt;i++)
{
cout<<prime[i]<<' ';
if(i%10==9) cout<<endl;
}
cout<<endl;
}
return 0;
}