欧拉筛选法

本文详细解析了欧拉筛选法,一种利用线性搜索策略找出2到n范围内素数的算法。核心在于通过标记合数的最小质因数来避免重复检查,时间复杂度为O(n),空间复杂度同样为O(n)。
摘要由CSDN通过智能技术生成

如有不当,欢迎指正!

2.欧拉筛选法(线性筛选法)

    1

    2

    3

    4

    5

    6

    7

    8

    9

   10

   11

   12

   13

   14

   15

   16

   17

   18

   19

   20

   21

   22

   23

   24

   25

   26

int flag[10000];     //flag标记非素数 非素数记为0

memset(flag,-1,sizeof(flag));

flag[1]=0;

int prime[10000];   //prime用来存放素数 类似数列

int cnt=0;   //当前prime有几个数据

int i,j; //循环控制变量

int n;

scanf("%d",&n);//输入n 研究到n的素数

for(i=2;i<=n;i++)     //外循环 从2n

{

        if(flag[i])        prime[++cnt]=i; //如果这个数没有在前几轮标记中被标记为素数 就认为它不是素数

        

        for(j=1;j<=cnt&&i*prime[j]<=n;j++) //内循环 从第一个素数开始

        {

                flag[i*prime[j]]=0;         //把外循环数字和到此为止每个素数的乘积标记为非素数

                if(i%prime[j]==0)        break;  //如果外循环数字是这个素数的若干倍 结束内循环

        }

        

}

for(i=1;i<=cnt;i++)  //输出

        printf("%d ",prime[i]);        

这个算法高明之处在于 每个要被筛去的数(即合数) 都只在自己最小质因数的内循环中被筛去

约定:p表示最小质因数 b表示倍数(外循环数) a表示某个要被筛去的数

几个疑难点:

1.为什么恒有b>=p

因为只有研究到b的时候,才能把b纳入prime

2.为什么a只能被最小质因数筛去

假如在某轮外循环中

a1=p1*b

a2=p2*b

a3=p3*b  检测到b%p3==0(或者说b/p3==n,n为整数) 中止 中止条件也可以理解为找到了b的最小质因数 因为是从最小质数往上找

a4=p4*b 假如不中止 将要进行的下一步

因为b%p3==n 所以a4=p4*p3*n p3才是b的最小质因数

当b'(指之后某一轮新的倍数)有b'=p4*n时会筛去 而这个b'=p4*n=p4*b/p3 >b(因为p4>p3)

3.怎么保证外循环的数在14行判断的时候 只要没有被前面的筛去就认为是素数

假如检测到a 而a是非素数(合数),

那么一定能表示为n3=p*b

而p<n3 在前面已经被找出(见1)

b<n3

但是怎么保证b不会因为中止条件而退出?

要让b不会因为中止条件退出 只要保证b的最小质因数大于或等于p

因为p是n3的最小质因数 所以b的最小质因数一定大于p

(假设p存在一个不等于p的最小质因数p' 那么p'也是n3的最小质因数 与p是n3的最小质因数矛盾)

这也保证了 检测到a为止 a及之前的所有质数和合数都被找出

这个算法的时间复杂度为O(n) 因为有几个数 就检测几遍

空间复杂度也为O(n)

故又称为线性筛

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值