python 快乐数判断_[Python 1] 如何使用Python找质数?

91e7d7edb93352d8e66a14b2c77a3e02.png

学习生物信息需要熟练掌握一门甚至多门编程语言,比如Python、R、C++,这取决于你的需求。

但语言只是工具,最关键的是如何合理使用工具去解决生物学问题,这需要你去多写、多查、多看来锻炼。不然给你把屠龙刀,你不去修炼,它也只是块废铁。工具有多好不仅取决于自身,更在于使用的人。

为了领略生物信息学的意义、美好、乐趣,之后我会分享更多文章,敬请期待~

本文内容主要包括:

  1. 质数和孪生质数的定义
  2. 质数分布的规律
  3. 两种实现方法,逐步优化~

为了更好的解决问题,我们先把“如何使用Python找质数”范围缩小一下,变成“如何使用Python找出100以内的素数”。

接下来,先明确概念,以便精确下手。

什么是质数?

质数( Prime number ):又称素数,指在大于1的自然数中,除了1和自身外,无法被其他自然数整除的数(也可定义为只有1和本身两个因素的数)。

与之相对的是合数指自然数中除了能被1和本身整除外,还能被其他数(0除外)整除的数。

试除法

根据质数的定义,可以有一个直观的思路:将

除以每个大于
且小于等于
的整数,如果不能被整除,结果有余数,那么
就为质数。

这种方法也叫试除法

#!/usr/bin/env python

最终得到 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]。和搜索结果一致~

ad9d1627b50737e8be0b4af15f5ed9d6.png
1到100的质数

提一句,代码中 if __name__ == '__main__' 如何正确理解?

在Python中,一个.py文件就是一个模块。一般情况下,模块名就是文件名。
__name__ 存放当前模块名,当模块被直接运行时模块名为 __main__ 。
所以,if __name__ = ' __main__' 表示:当模块被直接运行时,该行以下的代码块将被运行;当模块是被导入(import)时,代码块不被运行。

试除法虽然简单,但是在测试大整数时很快会变得不切实际。因为可能的约数数量会随着n的增加而迅速增加。根据素数定理,小于

的素数之数量大约为
。也就是说,采用试除法判断
,要除4.5亿次,对许多实际应用而言都太过庞大。

那么,有没有改进的方法呢?接着看下去吧~

质数分布规律

首先看一个关于质数分布的规律:大于等于5的质数一定和6的倍数相邻,例如5和7,11和13,17和19。

用符号表示更容易理解:当n≥5时,如果n-1和n+1都为质数,那么n一定是6的倍数。

如何证明这个规律呢?

证明:

为整数。

则大于等于

的自然数可表示如下:

即:

注意可以因式分解的式子。

其中,
可以被
整除,而
分别可以写成
的形式,所以它们都一定不是质数。

剩下的就是
,代入几个数字试一下:

x = 1 时,为5,7,11
x = 2 时,为11,13,17
可以看到11被计算了两次。能不能减少计算,更好的表示大于等于5的质数呢?
实际上,可以用
表示
。为什么呢?因为

所以大于等于5的质数可以表示为:
。这两个数都在
身边不离不弃。

以上即证明了 质数分布的规律:大于等于
的质数一定和
的倍数相邻。

我们来试试用Python实现这种思路,建议新手先自行尝试再看下面代码,更容易理解:

#!/usr/bin/env python

结果是[2, 3, 5, 7, 11, 13, 17, 19, 23, 25, 29, 31, 35, 37, 41, 43, 47, 49, 53, 55, 59, 61, 65, 67, 71, 73, 77, 79, 83, 85, 89, 91, 95, 97]。

相比之前试除法得出的[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97],多了几个合数,如25,55,49。

抓抓脑壳,究竟出了什么差错?

事实上,虽然质数是出现在

或是
的数列中,但是满足这个条件的数却
并不一定是质数。举个例子,6的4倍是24,它的两侧分别是23和25 ,但25不是质数。

问题来啦~

  1. 为什么满足
    或是
    (
    )的数不一定是质数?
  2. 如何从满足
    或是
    (
    )的数中进一步筛出质数?

先着手第一个问题,我们“改造”一下这两个式子:

可以看到,如果

是5或7的倍数,那么
(
)也是5或是7的倍数,它俩就不是质数了。

所以满足

或是
(
)的数不一定是质数。

所以如果想解决第二个问题,就得在代码中增加判断 n 是否为5或7的倍数。注意,这里n要大于7,不然会把5和7漏掉,它俩也是质数。

#!/usr/bin/env python

返回的结果是[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97],和试除法的结果一致。

同样的思路可以换一种方式写代码,另外也可以进一步使用time模块比较两种的时间:

#!/usr/bin/env python

到这里就大功告成啦~

为什么要比较代码运行时间?这一点可以查看如何理解算法时间复杂度的表示法,例如 O(n²)、O(n)、O(1)、O(nlogn) 等? 此知乎问题的回答都很优秀,值得了解!

想理解算法时间复杂度的表示法,先要搞明白何谓“算法时间复杂度”。
如果你学过开车的话(没有的话,回忆一下初中物理),就会知道,挂一档时,可能发动机转十几圈,车轮才转一圈;但挂5档时,可能发动机转一圈,车轮就转了一圈。
换句话说,在不同挡位,发动机转一圈,车轮转多少是不一样的。
这个玩意儿背后,其实就是初中学过的轮轴原理。
作者:invalid s

最后补充下“孪生质数猜想”:

孪生素数的问题已经有约200年的历史。
孪生质数”是指两个相差为2的质数,所以上面我们说的
也互为孪生质数。

孪生素数猜想”是说,存在无穷对孪生质数。在1900年的国际数学家大会上,希尔伯特将孪生质数猜想列入了他那著名的23个数学问题。
关于质数还有很多有趣的东西,比如梅森素数、数论。你可以自行了解,这里就不展开了。

现在,你学会了如何用Python找质数了吗?

参考:

  1. 质数-维基百科
  2. Python质数判断——菜鸟教程
  3. 判断一个数是否为质数的三种方法
  4. 如何用Python判断一个数是否是质数?
  5. 孪生素数猜想,张益唐究竟做了一个什么研究?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值