线性筛 埃式筛 欧拉筛

线性筛法求素数

题目:给出一个正整数n,打印出所有从1~n的素数(即质数);

普通解法

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
bool isprime(int n)
{
    if (n == 0 || n == 1)return false;
    for (int i = 2; i <=sqrt(n); i++)
        if (n%i == 0)return false;
    return true;
}
int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i <=n; i++)
    {
        if (isprime(i))printf(" %d", i);
    }
}

埃拉托斯特尼筛法

算法思路:算法从小到大枚举所有数,对于每一个素数,筛去它的所有倍数,剩下的就都是素数了。

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
bool p[1000];//是否被筛去,默认为false
int prime[1000], cnt = 0;
void findprime(int n)
{
    for (int i = 2; i <= n; i++)
    {
        if (!p[i])//没有被筛去的话
        {
            prime[cnt++] = i;//素数加1,
            for (int j = i + i; j <= n; j += i)//int j = i + i:从2开始,但是不能筛去2,所以从4开始
                p[j] = true;//筛去素数的倍数
        }
    }

}
int main()
{
    int n;
    scanf("%d", &n);
    findprime(n);
    for (int i = 0; i <cnt; i++)
    {
        printf(" %d", prime[i]);
    }
}

欧拉筛

算法思路:在埃氏筛法的基础上,让每个合数只被它的最小质因子筛选一次,以达到不重复的目的。

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
bool p[1000];
int prime[1000], cnt = 0;
void findprime(int n)
{
    for (int i = 2; i <= n; i++)
    {
        if (!p[i])//未筛去的话
            prime[cnt++] = i;//素数记录

        for (int j = 0; j < cnt; j++)
        {
            if (i*prime[j] <= n)//用i作为倍数,筛去prime[j]中的素数的倍数
            {
                p[i*prime[j]] = true;
                if (i%prime[j] == 0)break;
                //例子:i = 8 ,j = 1,prime[j] = 2,如果不跳出循环,prime[j+1] = 3,8 * 3 = 2 * 4 * 3 = 2 * 12,在i = 12时会计算。
            }
        }
                
    }

}
int main()
{
    int n;
    scanf("%d", &n);
    findprime(n);
    for (int i = 0; i <cnt; i++)
    {
        printf(" %d", prime[i]);
    }
}
原文地址:https://www.cnblogs.com/Jason66661010/p/12811300.html