zoukankan      html  css  js  c++  java
  • 算法:素数的筛法

    一 写在开头

    1.1 本文内容

    本文实现了素数的筛法算法。

    二 算法原理与实现

    在写代码的过程中,时不时会遇到求解素数的任务,特意将素数求解方法总结成文章以备不时之需。素数的求解算法大概有两种。一种是枚举某一范围的数,然后逐个判断该数是否为素数。这种方法简单但效率不高。另一种方法是使用素数的筛法将某一范围内的所有素数筛选出来,然后再打表。筛法的原理很简单:从最小的素数2开始,依次将2的倍数给剔除,然后将后面没有被剔除的最小素数3的倍数依次剔除......重复上述操作就可以将范围内的所有合数给剔除掉,剩下的自然就是素数。该算法可以使用C语言实现,如下面的代码所示。

     1 #include <string.h>
     2 
     3 /* 使用0和-1是为了使用内存填充函数memset */
     4 #define FALSE           (-1)
     5 #define TRUE            0
     6 #define MAX_RANGE_N     10000
     7 
     8 unsigned int counter = 0;
     9 static char indexs[MAX_RANGE_N];
    10 static int  primes[MAX_RANGE_N];
    11 
    12 void ScreenPrimes(char *indexs, int *primes, unsigned int *counter)
    13 {
    14     int i, j, k;
    15 
    16     /* 数组名做函数参数将退化成指针,因此需要乘于MAX_RANGE_N */
    17     memset(indexs, TRUE, sizeof(indexs[0]) * MAX_RANGE_N);
    18     indexs[0] = indexs[1] = FALSE;
    19 
    20     /* 筛选过程 */
    21     for (i = 2; i < MAX_RANGE_N; i++)
    22         if (indexs[i] == TRUE)
    23             for (j = i + i; j < MAX_RANGE_N; j += i)
    24                 indexs[j] = FALSE;
    25 
    26     /* 拷贝过程,其中k值表示范围内素数的个数 */
    27     k = 0;
    28     for (i = 0; i < MAX_RANGE_N; i++)
    29         if (indexs[i] == TRUE)
    30             primes[k++] = i;
    31     *counter = k;
    32 }

    值得注意的是在memset函数中,sizeof(indexs[0])返回一个unsigned int值,如果MAX_RANGE_N很大的话,其和MAX_RANGE_N相乘会有溢出的危险。

    有了上述的实现,要求打印前50个素数可以用下述代码实现。

     1 #include <stdio.h>
     2 #include <string.h>
     3 
     4 /* 使用0和-1是为了使用内存填充函数memset */
     5 #define FALSE           (-1)
     6 #define TRUE            0
     7 #define MAX_RANGE_N     10000
     8 
     9 unsigned int counter = 0;
    10 static char indexs[MAX_RANGE_N];
    11 static int  primes[MAX_RANGE_N];
    12 
    13 void ScreenPrimes(char *indexs, int *primes, unsigned int *counter)
    14 {
    15     int i, j, k;
    16 
    17     /* 数组名做函数参数将退化成指针,因此需要乘于MAX_RANGE_N */
    18     memset(indexs, TRUE, sizeof(indexs[0]) * MAX_RANGE_N);
    19     indexs[0] = indexs[1] = FALSE;
    20 
    21     /* 筛选过程 */
    22     for (i = 2; i < MAX_RANGE_N; i++)
    23         if (indexs[i] == TRUE)
    24             for (j = i + i; j < MAX_RANGE_N; j += i)
    25                 indexs[j] = FALSE;
    26 
    27     /* 拷贝过程,其中k值表示范围内素数的个数 */
    28     k = 0;
    29     for (i = 0; i < MAX_RANGE_N; i++)
    30         if (indexs[i] == TRUE)
    31             primes[k++] = i;
    32     *counter = k;
    33 }
    34 
    35 int main()
    36 {
    37     int i;
    38 
    39     ScreenPrimes(indexs, primes, &counter);
    40     for (i = 0; i < 50; i++)
    41         printf("%d ", primes[i]);
    42     putchar('
    ');
    43 
    44     return 0;
    45 }
  • 相关阅读:
    史上最全最新java面试题合集二(附答案)
    史上最全最新Java面试题合集一(附答案)
    修改vsftpd的默认根目录/var/ftp/pub到其他目录
    重置密码解决MySQL for Linux错误:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
    虚拟机下的Linux连接校园网上网问题
    CentOS7 安装Chrome
    CentOS7 卸载Firefox
    100个写作高级词
    【二叉搜索树】的详细实现(C++)
    【红黑树】的详细实现(C++)
  • 原文地址:https://www.cnblogs.com/laizhenghong2012/p/8728537.html
Copyright © 2011-2022 走看看