质数就是只能被1和本身整除的数。Eratosthenes筛选法是一种计算质数的有效方法。

这个算法的第一步就是写下所有从2至某个上限之间的所有整数。

在算法的剩余部分,遍历整个列表并剔除所有不是质数的整数。

后面的步骤是这样的。

找到列表中的第1个不被剔除的数(也就是2),然后将列表后面所有逢双的数都剔除,因为它们都可以被2整除,因此不是质数。

接着,再回到列表的头部重新开始,此时列表中第一个尚未被剔除的第1个数是3,所以在3之后把每逢第3个数(3的倍数)剔除。

完成这一步之后,再回到列表开头,3后面的下一个数是4,但它是2的倍数,已经剔除,所以将其跳过,轮到5,将所有5的倍数剔除。

这样依次类推、反复进行,最后列表中未被剔除的数均为质数。

编写一个程序,实现这个算法,

使用数组表示列表。

每个数组元素的值用于标记对应的数是否已被剔除。开始时数组所有元素的值都设置为TRUE,当算法要求“剔除”其对应的数时,就把这个元素设置为FALSE。

注意:

如果你的程序运行于16位的机器上,小心考虑是不是把某个变量声明为long。一开始先使用包含1000个元素的数组。如果你使用字符数组,使用相同的空间,你将会比使用整数数组找到更多的质数。

你可以使用下标来表示指向数组首元素和尾元素的指针,但你应该使用指针来访问数组元素。

除了2以外,所有偶数都不是质数,所以可以使程序的空间效率大大提高,方法是数组中的元素只对应奇数,这样,在相同的数组空间中,就可以寻找到得质数的个数大约是原来的2倍,

这个说明写了一大堆,其实步骤就是:
(1)读取队列中当前最小的数2,然后把2的倍数删去
(2)读取队列中当前最小的数3,然后把3的倍数删去
(3)读取队列中当前最小的数5,然后把5的倍数删去
…….
(n)读取队列中当前最小的状态为true的数n,然后把n的倍数删去

这个题目问题写了很多,不容易梳理清楚,首先我们要想办法跳过偶数(除2以外的其他偶数),只需要关心奇数;其次在剩下的奇数里面排除掉成倍数关系的数据(注意跳过偶数)。

我们的数据列表是2~n,第一个数是2,为了后面的程序循环逻辑更简单,这里直接输出为质数。我们的数据列表就变成了3~n这样的列表了,需要特别注意,特别小心的是,这里有3个列表,一个是数组里面保存的数据另一个是数据3~n还有一个就是数组的编号0~n, 这3个列表配合使用很容易让人头晕。

->指示的是数组序号

~>指示的是数组对应的数据(从3开始)

=>指示的是数据是数组实际保持的数据,代表是否被踢除。

题目要求的数据是从2开始,为了后面的算法实现方便,直接把2单独处理。所以number从3开始,但数组却从0开始的,这里需要进行转换 :数组起始地址+(number-3)就是number对应在数组中的位置。

这里由于要排除偶数,所以我们迭代时,number每次+2即可跳过偶数,所以 每次指针向前移动1个位置时,指针就指向了 数组起始地址+(number-3)/ 2 ,也就是每次向前移动一个位置。

然后需要剔除每次迭代后number的所有倍数:

​​​​​​​while(sp += number, sp < &sieve[SIZE]) {*sp = FALSE;
}

最后打印出所有剩下的质数:

第一个是2,然后number=3开始,每次+2迭代后就每次跳过了所有的偶数,判断对应的值判断是否该排除。

完整代码如下:

#include <stdio.h>#define TRUE 1
#define FALSE 0
#define SIZE 15void debug_info(char *sieve) {printf("\n-> : ");char *sp;int i;for(i = 0 ; i < SIZE; i++) {printf("%02d, ", i);}printf("\n~> : ");for(i = 3 ; i < SIZE; i++) {printf("%02d, ", i);}printf("\n=> : ");for(sp = sieve; sp < &sieve[SIZE]; sp++) {printf("%02d, ", *sp);}printf("\n\n");
}int main () {char sieve[SIZE];char *sp;int number;//初始化所有元素都为TRUEfor (sp = sieve; sp < &sieve[SIZE];) {*sp++ = TRUE;}debug_info(sieve);for(number = 3; number < SIZE ; number+=2) {sp = &sieve[0] + (number - 3) / 2;if(sp >= &sieve[SIZE]) {break;}//呈倍数关系的先移除printf("number = %d\n", number);while(sp += number, sp < &sieve[SIZE]) {*sp = FALSE;debug_info(sieve);}}printf("\nResult: 2,");for(number = 3, sp = &sieve[0]; sp < &sieve[SIZE], number < SIZE ; number +=2, sp++) {if(*sp) {printf("%d,", number);}}return 0;
}

我们看一下运行结果:

这个题目虽然有些绕,但是对数组的元素操作和算法思想有一定帮助。

C语言实现埃拉托色尼筛选法(剔除数组中的非质数)相关推荐

  1. c语言埃拉托色尼筛选法数组,埃拉托色尼筛选法 算法

    埃拉托色尼筛选法 埃拉托色尼选筛法(the Sieve of Eratosthenes)简称埃氏筛法,是古希腊数学家埃拉托色尼(Eratosthenes 274B.C.-194B.C.)提出的一种筛选 ...

  2. 埃拉托色尼筛选法c语言求最大公约数,用埃拉托色尼筛算法求两个数最大公约数C++的实现...

    #include "stdafx.h" #include "iostream" #include #include //使用埃氏筛选法求最大公约数 void s ...

  3. [编程] 2 python 实现埃拉托色尼筛选法

    1.1简介: 埃拉托色尼筛选法是用来生成质数的经典计算机编程算法,一般用来衡量计算机的速度. 我们知道,质数是能被自己和1整除的整数. 2,3,5,7,11都是质数. 那么算法是如何实现质数的识别呢? ...

  4. 埃拉托色尼筛选法 C++实现

    在公元前3世纪,古希腊天文学家埃拉托色尼发现了一种找出不大于n的所有自然数中的素数的算法,即埃拉托色尼筛选法. 具体筛选步骤: 这种算法首先需要按顺序写出2到n中所有的数. 然后把第一个元素画圈,表示 ...

  5. Day5:计数质数(埃拉托色尼筛选法)

    leetcode地址:https://leetcode-cn.com/problems/count-primes/ Day5:计数质数 一. 问题背景: 统计所有小于非负整数 n 的质数的数量. 二. ...

  6. Java实现埃拉托色尼筛选法

    1 问题描述 Compute the Greatest Common Divisor of Two Integers using Sieve of Eratosthenes. 翻译:使用埃拉托色尼筛选 ...

  7. python算法设计 - 埃拉托色尼筛选法

    python算法设计源码:https://github.com/MakerChen66/Python3Algorithm 版权声明:原创不易,本文禁止抄袭.转载,侵权必究! 目录 一.埃拉托色尼筛选法 ...

  8. JavaScript实现sieveOfEratosthenes埃拉托色尼筛选法算法(附完整源码)

    JavaScript实现sieveOfEratosthenes埃拉托色尼筛选法算法(附完整源码) sieveOfEratosthenes.js完整源代码 sieveOfEratosthenes.js完 ...

  9. 埃拉托色尼筛选法(Eratosthenes Sieve)分析

    最近看<java核心技术>看到集合章节,在最后位集(BitSet)部分给出了一个示例程序,使用了埃拉托色尼筛选法(Eratosthenes Sieve)求自然数2~n范围的所有素数 代码如 ...

最新文章

  1. 我在海外做产品的1000 天:三大观察与学习
  2. 微信小程序开发之微信支付
  3. R: ggplot2(1)
  4. VS code 使用 Remote-SSH 进行python远程开发
  5. spring mvc对异步请求的处理
  6. SSIS [大容量插入任务] 找不到文件错误
  7. 鼠标移到图片上,图片放大
  8. pscad仿真数据提取方法
  9. c#控件chart制作自动更新的温湿度实时曲线图
  10. 【深度学习】U-Net简介
  11. 软素质面试题分享以及一些面试技巧和面试礼仪
  12. 计算机类毕业设计评阅书评语,本科毕业论文评阅人评语_毕业论文评阅人评语模板文库_本科毕业论文评阅老师评语大全...
  13. TF卡文件系统变RAW怎样解决
  14. 虚拟机服务器渗透,对一台虚拟主机服务器的渗透 -电脑资料
  15. python画图设置坐标轴为科学记数法_防止matplotlib.pyplot中的科学记数法
  16. 示波器测量的波形一直抖动怎么办
  17. ts promise
  18. com.google.zxing 二维码工具类
  19. Dockerfile 的 CMD 与 ENTRYPOINT 傻傻分不清楚
  20. 『NLP经典项目集』06: 使用预训练模型ERNIE-GEN自动写诗

热门文章

  1. 04.freetype显示中文
  2. WGS84与GCJ02、BD09经纬度坐标转换介绍
  3. 入门nosql数据库(非关系型数据库)
  4. Windows10 无法正常搜狗和搜狗输入法
  5. OpenCV提取图像中的垂直线(或者水平线)
  6. java消息中间件_java消息中间件
  7. sFlow的安装和使用
  8. 蒜头君的藏书(映射)
  9. Java 小项目 01 简单记账软件
  10. 怎么用计算机算出锁屏密码,电脑怎么设置锁屏密码