欧拉筛法与埃氏筛法(求素数)

本文深入探讨埃氏筛法与欧拉筛法在筛选素数过程中的原理与实现,埃氏筛法通过标记合数筛选素数,而欧拉筛法优化标记过程,避免重复标记,提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

埃氏筛法

基本思想 :从2开始,将每个质数的倍数都标记成合数,剩下的没有被标记的就是素数,从而达到筛选素数的目的.

代码实现:

int vis[maxn]={0};  
void prime(){
    vis[0] = vis[1] = 1;  //0 和 1不是素数
    for (int i = 2; i <= maxn; i++)
     {
        if (!vis[i])
         {         //如果i是素数,让i的所有倍数都不是素数
            for (int j = i*i; j <= maxn; j += i)
             { 
                vis[j] = 1;
             }
         }
    }

vis[i]数组是标记素数,如果i是素数,则vis[i]=0,否则vis[i]=1;

欧拉筛法

在埃氏筛法中,有些数会被标记多次,例如30=2 * 15=3 * 10=5 * 6被标记了3次
因此为了解决重复标记问题,出现了欧拉筛法,它是根据每个合数只有一个最小质因子,因此欧拉筛法中每个合数 m 只能根据 m 最小的质因子的倍数所标记
代码实现:

int p[maxn]={0};
int vis[maxn]={0};
void prime()
{
    int t=0;
    for(int i=2;i<=maxn;i++)
    {
        if(!vis[i])
        {
            t++;
            p[t]=i;
        }
        for(int j=1;j<=t&&i*p[j]<=maxn;j++)
        {
            vis[i*p[j]]=1;
            if(i%p[j]==0)
                break;
        }
    }
}

p[i]数组记录的是各个素数,t是素数的个数(t是随着程序的进行而增加的),很显然欧拉筛法中p[j]是最小的质因子,每个合数是根据它的倍数即I*p[j]所标记;
重点解释if(i%p[j]==0) break;是因为当i是p[j]的倍数的时候,i=k * p[j],如果循环继续下去,则需标记i * p[j+1],而i * p[j+1]=p[j] * k *p[j+1]其中p[j]是最小素数,但i * p[j+1]是用p[j+1]的倍数所标记的,当j=k * p[j+1],则会重复标记此书
例如:i=8;j=1;p[j]=2; i/p[j]=4; p[j+1]=3; 3 * 8=3 * 2 4=2 * 12;
当i=12时,j=1时,i
p[j]=24被标记,而不是用8 * p[2]=24标记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值