对你有帮助别忘了给我点个赞哦~

将近50本能让程序员进入大厂应该精读的神书,免费 送给大家!只需要关注文章底下的公众号即可获得

我们要判断素数,首先要知道素数的定义。

素数:质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数。

知道了素数的定义,那么我们应该想一下,如何去判断一个数是否为素数?

一种思路是,我们在每次得到一个数后,都去计算,去尝试因式分解它,看它除了1和自身之外还有没有其他因子
另一种是,我们去查阅素数表,看这个数在不在素数表上。那我们就要先得到素数表。

以下除了第一种方法,第2~4种方法都是用第二种思路做的
当要判断的目标数很少时,第一种高效。但是当给定的目标数组很多,数也很大时。后面的思路配上高效的查找算法,显然更高效


方法1:暴力求解

1-1:稍微动动脑

思想
根据素数的定义思考。素数是大于1的自然数,除了1和自身外,其他数都不是它的因子。
那我们就可以用一个循环,从2开始遍历到这个数减去1,如果这个数都不能被整除,那么这个数就是素数。
也就是说:
给定一个数 n , i 从 2 开始取值,直到 n - 1(取整数),如果 n  %  i != 0 , n 就是素数
进一步思考,有必要遍历到 n - 1 吗?
除了1以外,任何合数最小的因子就是2,那最大的因子就是 n/2
那我们就遍历到 n/2就足够了

这样我们就可以写出这个算法的核心代码:

int isPrime(int target) {int i = 0;if (target <= 1) {printf("illegal input!\n");//素数定义return -1;}for (i = 2; i <= target / 2; i++) {if (target % i == 0)return 0;//不是素数直接返回0}return 1;//是素数返回1
}

1-2:再进一步

思想

在上面的基础上,其实不需要遍历到 n/2,只需要到 根号n(包含根号n) 就可以了。为什么呢?这是个数学问题,大家自行思考一下。

核心代码:

int isPrime(int target) {int i = 0;if (target <= 1) {printf("illegal input!\n");//素数定义return -1;}for (i = 2; i <= (int)sqrt(target); i++) {if (target % i == 0)return 0;}return 1;
}

从第二种方法开始,我们都是先完成判断素数数组,然后用二分法去查找判断数组

这里说一下以下三种方法牵扯的概念:

  • 范围:1 ~ 范围上限N

  • 范围上限N:判断素数需要用户输入随机素数,这个随机素数的范围是1 ~ N

  • 判断素数数组:将数组的下标1 ~ N的自然数一一对应起来。
    判断 1到N 的自然数是否为素数,其实就是判断数组的下标是否为素数,如果是 给这个下标所对应的判断素数数组元素赋1,否则赋0
    比如:我要判断3是否为素数,我们就找到判断素数数组isPrime中的下标为3的元素,即:isPrime[3]
    如果 3 是素数 ,   赋值1,即isPrime[3] = 1
    如果 3 不是素数,赋值0 ,即isPrime[3] = 0
    这样我们在用二分法查找时,查找数组下标就可以,找到下标后返回下标对应的判断素数数组的值。
    如果是1说明下标对应的自然数是素数,否则不是


方法2:用素数表来判断素数

思路
如果一个数不能整除比它小的任何素数,那么这个数就是素数
这种“打印”素数表的方法效率很低,不推荐使用,可以学习思想

核心代码:

//target:输入的要查找的数
//count:当前已知的素数个数
//PrimeArray:存放素数的数组
int isPrime(int target, int count, int* PrimeArray) {int i = 0;for (i = 0; i < count; i++) {if (target % PrimeArray[i] == 0)return 0;}return 1;
}

方法3:普通筛法——埃拉托斯特尼(Eratosthenes)筛法

思路:
1. 我们的想法是,创建一个比范围上限大1的数组,我们只关注下标为 1 ~ N(要求的上限) 的数组元素与数组下标(一一对应)。
2. 将数组初始化为1。然后用for循环,遍历范围为:【2 ~ sqrt(N)】。如果数组元素为1,则说明这个数组元素的下标所对应的数是素数。
3. 随后我们将这个下标(除1以外)的整数倍所对应的数组元素全部置为0,也就是判断其为非素数。
这样,我们就知道了范围内(1 ~ 范围上限N)所有数是素数(下标对应的数组元素值为1)或不是素数(下标对应的数组元素值为0)

用百度百科对埃拉托斯特尼筛法简单描述:要得到自然数n以内的全部素数,必须把不大于 的所有素数的倍数剔除,剩下的就是素数。

核心代码:

//                 判断素数的数组    范围上限N
void Eratprime(int* isprime, int upper_board) {int i = 0;int j = 0;//初始化isprimefor (i = 2; i <= upper_board; i++)isprime[i] = 1;for (i = 2; i < (int)sqrt(upper_board); i++) {if (isprime[i]) {isprime[i] = 1;}for (j = 2; i * j <= upper_board; j++) {//素数的n倍(n >= 2)不是素数isprime[i * j] = 0;}}}

方法4:线性筛法——欧拉筛法

思路:
我们再思考一下上面的埃拉托斯特尼筛法,会发现,在“剔除“非素数时,有些合数会重复赋值。这样就会增加复杂度,降低效率。
比如:范围上限N = 16时

2是素数,剔除”2 的倍数“,它们是:4,6, 8,10, 12, 14, 16
3是素数,剔除”3 的倍数”,它们是,6,9,12,15

6,12是重复的。如何减少重复呢?

核心代码:

void PrimeList(int* Prime, bool* isPrime, int n) {int i = 0;int j = 0;int count = 0;if (isPrime != NULL) {//确保isPrime不是空指针//将isPrime数组初始化为 1for (i = 2; i <= N; i++) {isPrime[i] = true;}}if (isPrime != NULL && Prime != NULL) {//从2遍历到范围上限Nfor (i = 2; i <= N; i++) {if (isPrime[i])//如果下标(下标对应着1 ~ 范围上限N)对应的isPrime值没有被置为false,说明这个数是素数,将下标放入素数数组Prime[count++] = i;//循环控制表达式的意义:j小于等于素数数组的个数 或 素数数组中的每一个素数与 i 的积小于范围上限Nfor (j = 0; (j < count) && (Prime[j] * (long long)i) <= N; j++)//将i强制转换是因为vs上有warning,要求转换为宽类型防止算术溢出。数据上不产生影响{isPrime[i * Prime[j]] = false;//每一个素数的 i 倍(i >= 2)都不是素数,置为false//这个是欧拉筛法的核心,它可以减少非素数置false的重复率//意义是将每一个合数(非素数)拆成 2(最小因数)与最大因数 的乘积if (i % Prime[j] == 0)break;}}}
}

如果你没有理解,可以参考下例

以上四种算法的完整代码在我的github上,帮助到你了不妨给我点个star哦~


本来文章到这了就结束了,但是考虑到特殊时期,各位同学在家应该待得有点无聊了,优秀的各位应该会充分利用时间,多看书,多学习。那么在下面推荐一些我往期的干货文章,希望对大家有帮助!

推荐阅读:

精选教学:

操作符详解(上)

那些关于函数我们容易忽略的基础知识

C语言:

C语言复习巩固(一)

C语言复习巩固(二)

C语言复习巩固(三)

C语言复习巩固(四) 函数

C语言复习巩固(五) 指针(初阶)

猜数字小游戏详解 如何用rand,srand,time来完成随机数发生

C语言游戏之扫雷

三子棋C语言实现

C++:

C++入门(一)

C++入门(二)


除此之外,我整理了将近50本学习 C/C++/linux/unix/网络/算法 必读的好书,在这里以电子书的形式免费送给各位未来的精英们。只需要关注我的公众号,后台回复:[好书] 即可获得网盘链接

最后,感谢大家的观看,有什么问题都可以在下方评论区评论或者公众号后台回复,看到我就会回复大家!

在这里祝各位健健康康过一个充实的假期!


感谢指出我错误的微信网友: 大异小同 。

本次修改内容:

1. 1-1中的代码,for循环的循环控制 i < target / 2 改为 i <= target

错误情况:当 target == 4 时,target / 2 的值是 2,i 从 2开始,如果 循环控制是:i < target / 2, 则不会进入 for 循环,所以会将 4 误判为素数

2. sqrt 函数的返回值是 double 类型。

将 i <= sqrt(target) 改为 i <= (int)sqrt(target)

sqrt 函数的函数原型:double sqrt(double arg);

2020 - 2 - 24 日修改:

你不知道的几种素数判断方法,由浅入深,详解。(附送程序员必读好书)相关推荐

  1. 史上最全 JVM 大全详解、java 程序员细节到极致的一次,魔鬼

    前言 作为 Java 的从业者,在找工作的时候,一定会被问及关于 JVM 相关的知识. JVM 知识的掌握程度,在很多面试官眼里是候选人技术深度的一个重要评判标准.而大多数人可能没有对 JVM 的实际 ...

  2. 史上最全 JVM 大全详解!java 程序员细节到极致的一次,魔鬼

    前言 作为 Java 的从业者,在找工作的时候,一定会被问及关于 JVM 相关的知识. JVM 知识的掌握程度,在很多面试官眼里是候选人技术深度的一个重要评判标准.而大多数人可能没有对 JVM 的实际 ...

  3. cat命令详解_好程序员Python培训之详解eval好与坏

    好程序员Python培训之详解eval好与坏,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,下面我们一起来看一下吧. eval是Python的一个内置函数,这个函数的作用 ...

  4. “史上最全”Spring Boot详解!java程序员细节到极致的一次,魔鬼

    这本书的灵感 当时公司的技术栈全面转入Spring Boot体系,源于本书作者在公司的一次分享会上的分享.当时作者用了不到10分钟就使用Spring Boot轻松制作了一个功能完整的数据增加.删除.修 ...

  5. python的sort方法是哪种_python中的sort方法使用详解

    Python中的sort()方法用于数组排序,本文以实例形式对此加以详细说明: 一.基本形式列表有自己的sort方法,其对列表进行原址排序,既然是原址排序,那显然元组不可能拥有这种方法,因为元组是不可 ...

  6. mvc ajax提交html标签,Mvc提交表单的四种方法全程详解

    Mvc提交表单的四种方法全程详解 2019-01-05 编程之家 https://www.jb51.cc 编程之家收集整理的这篇文章主要介绍了Mvc提交表单的四种方法全程详解,编程之家小编觉得挺不错的 ...

  7. 安卓判断服务器返回的状态码,关于服务器返回的十四种常见HTTP状态码详解

    原标题:关于服务器返回的十四种常见HTTP状态码详解 HTTP状态码 状态码是由3位数字和原因短语组成的(比如最常见的:200 OK),其中第一位数字表示响应类别,响应类别从1到5分为五种 add:其 ...

  8. android 实现毫秒定时器,Android实现定时器的五种方法实例详解

    一.Timer Timer是Android直接启动定时器的类,TimerTask是一个子线程,方便处理一些比较复杂耗时的功能逻辑,经常与handler结合使用. 跟handler自身实现的定时器相比, ...

  9. 设计模式——模版方法模式详解(论沉迷LOL对学生的危害)

    0. 前言 写在最前面,本人的设计模式类博文,建议先看博文前半部分的理论介绍,再看后半部分的实例分析,最后再返回来复习一遍理论介绍,这时候你就会发现我在重点处标红的用心,对于帮助你理解设计模式有奇效哦 ...

  10. golang导入git包_使用go module导入本地包的方法教程详解

    go module 是Go1.11版本之后官方推出的版本管理工具,并且从 Go1.13 版本开始, go module 将是Go语言默认的依赖管理工具.到今天 Go1.14 版本推出之后 Go mod ...

最新文章

  1. IDOC 创建,增强,管理,配置
  2. CentOS各个版本国内镜像下载地址,下载速度10M+
  3. StoryBoard解惑
  4. 霍金一生重要时刻照片合集,3次来中国,年轻时也是帅哥一枚
  5. websocket没准备好如何解决_那些很重要,但是不常用的技术,websocket
  6. c语言高低位拷贝_C语言指针详解
  7. java异常没有catch住_今天才真正了解Java的异常处理
  8. 谷歌悄悄修复4个 0day
  9. linux系统yum提示注册,Linux:redhat6.5使用yum时提示需要注册问题解决方案
  10. 唧唧Down(B站视频下载) 彻底解决你的B站视频下载问题
  11. 如何在arcgis中制作土地利用转移矩阵
  12. 【026】国务院督查组莅临翼辉信息参观调研
  13. win10退出微软账号
  14. 正在保存备份的驱动器与启动计算机,如何创建和使用Dell Recovery Restore USB驱动器...
  15. 最近很多人问我:saiku下载不下来
  16. 互联网早报:腾讯推出“电子签平台” 用微信就能开出具备法律效力的电子收据
  17. C语言——任意分数化简
  18. 【java基础面试题】
  19. 地方门户网站SEO 重点做长尾词
  20. 论文阅读笔记(五)CLIP4Clip: An Empirical Study of CLIP for End to End Video Clip Retrieval

热门文章

  1. 又一程序员猝死...
  2. apple开发者账号区别
  3. 香港服务器低价租用内幕
  4. 嵌入式平台 STM32 libqrencode 移植 二维码生成
  5. C++(35)——判断一个数能否同时被3和5整除
  6. 【Python实例学习】用Python的xlsxwriter模块,进行Excel表格插入图标的操作
  7. matlab 简单算例,MATLAB 3D 动画简单实例 | 学步园
  8. rancher部署安装好后,无法部署pod
  9. 2019级软件工程应用与实践-人工智能快递柜(代码分析9)
  10. 啥?学习微服务,你竟然不知道什么是熔断,降级和限流