筛选素数的三种方法

判断一个数是不是素数,相信大家都知道,那么如果每一个数,都规规矩矩的使用判断[1,本身]是否有除了本身和1,以外的可以整除的数,这样的做法显然不可取的,如果查看1~n的素数,这样的时间复杂度为 O(n^2)

1.朴素筛法

这个筛法的思想是,每一次把枚举到的数x的倍数筛选掉,这样就可以优化一些时间复杂度为 O(N*lnN)
具体代码

#include 

using namespace std;

int n,cnt;
const int N=1e6+10;
int prime[N];
bool st[N];

void get_prime(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(!st[i]) 
        {
            prime[cnt++]=i;
        }
        for(int j=i;j<=n;j+=i)
        {
            st[j]=true;
        }
    }
}


int main()
{
    cin>>n;
    get_prime(n);
    cout<<cnt<<endl;
    return 0;
}

2.埃氏筛法

在朴素筛法的基础上简单优化
我们只需要将素数的倍数筛除,这样就可以把不是素数的数筛选掉了
具体代码

#include 

using namespace std;

int n,cnt;
const int N=1e6+10;
int prime[N];
bool st[N];

void get_prime(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(!st[i]) 
        {
            prime[cnt++]=i;
            for(int j=i;j<=n;j+=i)
            {
                st[j]=true;
            }
        }
        
    }
}


int main()
{
    cin>>n;
    get_prime(n);
    cout<<cnt<<endl;
    return 0;
}

埃氏筛法比朴素筛法速度快一倍左右

3.线性筛法

前面两种筛法会将同一个元素筛除多次,时间比较长,那么有没有一种算法可以优化,把一个元素的筛除次数减少。线性筛法的诞生了。
一个数一定是被它的最小因数筛除的(1除外)而且这样因数是质素。
那么代码是怎么样的

#include 

using namespace std;

int n,cnt;
const int N=1e6+10;
int prime[N];
bool st[N];

void get_prime(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(!st[i]) 
        {
            prime[cnt++]=i;
        }
        for(int j=0;prime[j]<=n/i;j++)
        {
            st[prime[j]*i]=true;
            if(i%prime[j]==0) break;//被最小因素筛除
        }
        
    }
}


int main()
{
    cin>>n;
    get_prime(n);
    cout<<cnt<<endl;
    return 0;
}

你可能感兴趣的:(算法,c++)