• 几种素数筛法


      素数的求解是数论题目中频繁遇到的问题,下面介绍几种求 n 以内的素数的算法

    全局定义:

    1 const int n = ?;        //n范围
    2 const int ma = ?;        //素数个数
    3 bool nu[n];            //标记数组
    4 int phi[ma];            //存素数
    5         

    1、较为高效的筛法

      思想:从 2 开始,即标记数组为0(或为1),当标记数组为 0(或1) 时,该数为素数,把素数的倍数筛掉。此算法缺陷在于会重复筛选有不同素数因子的合数(比如说6,被2筛一次,又被3筛一次)

    代码:

     1 void prime1()            //因为标记的时候会出现大量重复
     2 {
     3     memset(nu, 0, sizeof(nu));
     4     int k = 0;
     5     for(int i = 2; i < n; ++i)
     6         if(!nu[i])
     7         {
     8             phi[k++] = i;
     9             for(int j = i*i; j < n; j += i)
    10                 nu[j] = 1;
    11         }
    12 }

    2、线性筛法

      线性筛法就是为了避免重复筛掉同一个合数。思想是:从2 开始遍历,遇到素数就记录下来,当 i 遍历到为前面已经存储的素数的倍数的时候,就跳出循环,这样不仅可以筛选出所有素数,而且避免了重复。

    代码:

     1 void prime2()        //线性筛法
     2 {
     3     memset(nu, 0, sizeof(nu));
     4     int k = 0;
     5     for(int i = 2; i < n; ++i)
     6     {
     7         if(!nu[i])    phi[k++] = i;
     8         for(int j = 0; (j<k && i*phi[j]<n ); ++j)
     9         {
    10             nu[i*phi[j]] = 1;
    11             if(i%phi[j] == 0)    break;
    12         }
    13     }
    14 }

    优化:

    优化原理:除了2以外,所有素数都是奇数,所以排除2以后,i 就可以不管偶数了,值得注意的是,排除 2 之后,nu[4] 要清除标记。

    代码:

     1 void prime3()    //线性筛法改良
     2 {
     3     memset(nu, 0, sizeof(nu));
     4     int  k = 1;
     5     phi[0] = 2, nu[4] = 1;
     6     for(int i = 3; i < n; i += 2)
     7     {
     8         if(!nu[i])    phi[k++] = i;
     9         for(int j = 0; (j<k && i*phi[j]<n); ++j)
    10         {
    11             nu[i*phi[j]] = 1;
    12             if(i%phi[j] == 0)    break;
    13         }
    14     }
    15 }
  • 相关阅读:
    如何添加“写字板”打开方式
    UML类图聚集与组合的区别
    系统调用跟驱动程序中相应函数的参数对应关系
    PHP 判断数据类型
    PHP连接MySQL数据库的三种方式(mysql、mysqli、pdo)
    java 中的内部类总结
    cross-env使用笔记
    MySQL——约束(constraint)详解
    MySQL数据库--外键约束及外键使用
    Java中Lambda表达式的使用
  • 原文地址:https://www.cnblogs.com/Duahanlang/p/3212323.html
Copyright © 2020-2023  润新知