质数的筛选( 主要介绍 筛法 线性筛 )(有好的方法后续会补上 未完待续)

一 埃拉托斯特尼筛法(思路非常好 就是复杂度有点高 )(  o(nlognlogn)  )

  原理 质数的倍数不是质数 一个数不是比他小的数(1除外)的倍数这个数是质数。

  2是质数 4,6,8,10....不是质数(打个标记)

  3是质数(没有被标记) ,6,9,....不是质数(同样打标记)

  4不是质数(被标记)

  5是质数(没有被标记)  5.10......不是质数(标记)    

  这样递推下去  就可以得到所有质数 

  ******推荐找1e5内的所有质数 太大了复杂度就太高了

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
bool prime[maxn];
int p[maxn];
vector<int> vs;
void findprime()
{
    for(int i = 2; i < maxn; i ++)  prime[i] = true;
    for(int i = 2; i < maxn; i ++){
        if(prime[i])
        {
            vs.push_back(i);
            for(int j = i*2; j < maxn; j += i)
            {
                prime[j] = false;
            }
        }
    }
}
int main()
{
    findprime();
    cout<<vs.size()<<endl;
}

   其实在找的时候大多数都重复了 例如10 在2的时候标记了 在5的时候也标记了 其实5去标记其他数的时候可以从 5*5开始 (注意1e5时候i*i会爆int)

#include<bits/stdc++.h>
#define int long long using namespace std; const int maxn=1e5+5; bool prime[maxn]; int p[maxn]; vector<int> vs; void findprime() { for(int i = 2; i < maxn; i ++) prime[i] = true; for(int i = 2; i < maxn; i ++){ if(prime[i]) { vs.push_back(i); for(int j = i*i; j <maxn; j += i) { prime[j] = false; } } } } int32_t main() { findprime(); cout<<vs.size()<<endl; }

二 线性筛

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
bool prime[maxn];
int p[maxn];
int tot;
vector<int> vs;
void findprime()
{
    for(int i = 2; i < maxn; i ++)  prime[i] = true;
    for(int i = 2; i < maxn; i ++)
    {
        if(prime[i]) p[++tot]=i,vs.push_back(i);
        for(int j=1;j<=tot && i*p[j]<maxn; j++)
        {
            prime[i*p[j]]=false;
            if(i%p[j]== 0) break;
        }
    }
}
int main()
{
    findprime();
    cout<<vs.size()<<endl;
}
原文地址:https://www.cnblogs.com/Andromeda-Galaxy/p/9746773.html