筛法求素数(普通方法和快速筛)

1.普通的线性筛

原理:素数的倍数是合数,合数的倍数还是合数,把所求区间的合数全都去掉了,剩下的就是素数了

模板:

#include <iostream>
#include <string>
#include <cstdio>
#include <string.h>
#define maxx 20    //maxx是几就表明要求的是 : 从一到几这个范围内的素数

using namespace std;

int su[maxx];//这里面存放的是素数
int book[maxx + 5];//su:素数集合,book[]标记是否为素数,注意一定要加x否则数组溢出特别难查出来
int cnt;//cnt代表的是在su[]这个数组中,因为要往里塞题给范围内的素数嘛,所以这个cnt就是塞素数时的下角标,当然了,还充当输出时的输出上界
void xianxingshai()
{
    cnt=1;
    memset(book,-1,sizeof(book));
    for(int i=2;i<maxx;i++)
    {
        if(book[i]==-1)
        {
            su[cnt++]=i;
        }
        for(int j=i*2;j<maxx;j+=i)
            book[j]=0;
    }
}

int main()
{
    xianxingshai();
    for(int i=1;i<cnt;i++)//因为到最后cnt还是有一个++,故是 i<cnt 而非 i<=cnt
    {
        cout<<su[i]<<" ";
    }
    return 0;
}

2.快速线性筛法

这里有一个大佬的博客https://blog.csdn.net/yangyuhao0408/article/details/50956143(就只看他快速线性筛法那部分就行,和下面这个的代码和思路是一样的,下面这个代码里还有解释)

模板:

#include<iostream>
#include <cstdio>
#include <string.h>
#include <cstring>

using namespace std;

#define maxx 200  //maxx是几就表明要求的是 : 从一到几这个范围内的素数
long long prime[maxx+5];//这个集合中存的是质数的集合
long long num_prime;//num_pirme记录素数个数
int book[maxx];//book[]为-1是素数,为0是合数
void quick_su()
{
    memset(book,-1,sizeof(book));
    num_prime=0;
    book[0]=book[1]=0;
    for(long long i=0;i<=maxx;i++)
    {
        if(book[i]==-1)
        {
            prime[num_prime++]=i;
        }
        for(long long j=0;j<num_prime&&i*prime[j]<=maxx;j++)
        {
            book[i*prime[j]]=0;//是合数故标记为0,同时,prime[j]是合数i*prime[j]的最小素因子
            if( !(i%prime[j]) )//即比一个合数大的质数和该合数的乘积可用一个更大的合数和比其小的质数相乘得到
                break;
        }
    }
}
int main()
{
    quick_su();
    for(int i=0;i<num_prime;i++)//输出
    {
        printf("%lld  ",prime[i]);
    }
        printf("\n");
    return 0;

}

猜你喜欢

转载自blog.csdn.net/qq_41764621/article/details/81436279