算法杂谈埃氏素数筛

Posted Jiaxin-Li

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法杂谈埃氏素数筛相关的知识,希望对你有一定的参考价值。

【今天我们来讲讲筛子】

【埃氏筛的基本思想】

简单来说就是把不大于技术分享(n为数据范围)以内的素数的倍数全都去掉,那么剩下的就是2~n之间的素数了。

【举个例子】

我们假设现在n是25。

第一步:先把2作为筛子,那么所有2的倍数都被筛掉了。

则当前序列为:2 3 5 7 9 11 13 15 17 19 21 23 25

第二步:剩下的序列中第一个素数是3,将序列中3的倍数划掉。

则当前序列为:2 3 5 7 11 13 17 19 23 25

25仍然大于3的平方,所以我们还要继续筛

现在序列中第一个素数是5,同样将序列中5的倍数划掉。

则当前序列为:2 3 5 7 11 13 17 19 23

因为23小于5的平方,跳出循环

So 最后的答案就是:2 3 5 7 11 13 17 19 23 啦

是不是很简单?

哦,忘说了,这种方法的时间复杂度是O(n log n)。

想要更快的吗,还有线性筛呢!!!

【参考代码】

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const long long maxn=10000007+10;
const long long maxp=700000;
int vis[maxn];
long long prime[maxp];
long long n;

long long gen()
{
    long long m=(long long)sqrt(n+0.5);
    memset(vis,0,sizeof(vis));
    vis[2]=0;
    for(long long i=3;i<=m;i=i+2)
	{
        if(!vis[i])for(long long j=i*i;j<=n;j+=i) vis[j]=1;
        if(i*i>n)break;
    }
    long long c=1;
    prime[0]=2;
    for(long long i=3;i<=n;i=i+2) if(!vis[i]) prime[c++]=i;
    return c;
}
int main()
{
    long long c;
    cin>>n;
    c=gen();
    for(long long i=0;i<c;i++) printf("%lld ",prime[i]);
    cout<<endl<<c;
    return 0;
}

 【实际应用】

找素数啊,这还用说吗???

以上是关于算法杂谈埃氏素数筛的主要内容,如果未能解决你的问题,请参考以下文章

素数筛法(筛线性筛+埃氏筛)

素数筛 埃氏筛法

线性筛素数

素数筛( 埃氏筛线性筛区间筛)

素数表的获取(埃氏筛和欧拉筛)

埃氏筛法(素数筛)