[超详细]3种方法判断一个数是否为质数(Python)

文章讲述了如何通过数学方法判断一个数是否为质数,介绍了两种方法,一种是检查小于等于√t的因数,另一种是利用6x-1和6x+1的模式简化判断过程,降低时间复杂度至O(√t)。
摘要由CSDN通过智能技术生成
        # 整除就是余数为0 只要有一个被整除 就找到因数 就不是质数
        return False
return True

t = int(input())
print(is_zhishu(t))


方法二:一个数t,其必然可以拆解为![$t = \sqrt{t}\times\sqrt{t}$](https://latex.csdn.net/eq?%24t%20%3D%20%5Csqrt%7Bt%7D%5Ctimes%5Csqrt%7Bt%7D%24),则其整数因数必然一个不大于![$\sqrt{t}$](https://latex.csdn.net/eq?%24%5Csqrt%7Bt%7D%24),一个不小于![$\sqrt{t}$](https://latex.csdn.net/eq?%24%5Csqrt%7Bt%7D%24).因此可以只搜索小于等于![$\sqrt{t}$](https://latex.csdn.net/eq?%24%5Csqrt%7Bt%7D%24)的因数即可,将上述代码小改一下即可。此时时间复杂度就只需要O(![$\sqrt{t}$](https://latex.csdn.net/eq?%24%5Csqrt%7Bt%7D%24)).


代码:



判断是否为质数

import math
def is_zhishu(t):
if t <= 1:
# 1和0都不是质数
return False
sqrt_t = math.ceil(t**0.5) # 这里用ceil的原因是要取整数才能输入range
for i in range(2, sqrt_t):
if t % i == 0:
# 整除就是余数为0 只要有一个被整除 就找到因数 就不是质数
return False
return True

t = int(input())
print(is_zhishu(t))


![](https://latex.csdn.net/eq?)方法三:时复<=O(![$\sqrt{t}$](https://latex.csdn.net/eq?%24%5Csqrt%7Bt%7D%24)).


方法三基于如下一个规律:


首先。对于任一个自然数t,只要t>=5, 则可以写成6x-1,6x,6x+1,6x+2,6x+3,6x+4,...(x>=1)中的任一个。其次,针对上面的这种表达,依次看其是否是质数。


* 6x-1: 不能确定(因为像35=6\*6-1不是质数,但41=6\*7-1是质数,因此暂时不能确定)
* 6x: 因数可以是2,3,6,必定不是质数
* 6x+1: 不能确定(因为像25=4\*6+1不是质数,但37=6\*6+1是质数,因此暂时不能确定)
* 6x+2: =2(3x+1)因数可以是2,必定不是质数
* 6x+3: =3(2x+1)因数可以是3,必定不是质数
* 6x+4: =2(3x+2)因数可以是2,必定不是质数


因此,对于t>=5,只有t可以写成t=6x-1或者t=6x+1(x>=1)时**才有可能**是质数。那么判断t是否可以写成这两种形式该如何体现在代码上呢?


* 首先我们知道代码中t%6 == 1,表示t = 6x+1(x>=0)的t都能识别出来,因此判断t>=5时可以被写成这种形成t=6x+1(x>=1)的就直接用t%6 == 1来判断即可,因为可以被识别出来即可。
* 而t=6x-1(x>=1),这个-1的要如何识别出来呢?这个直接体现是体现不了在余数上的,因此需要转换一下,t=6x-1(x>=1)等价于t=6(x+1)-1(x>=0)=6x+5(x>=0). 类似上一个所说,t%6 == 5,表示t = 6x+5(x>=0)的t都能识别出来.因此这时只需要用t%6 == 5来识别t=6x-1(x>=1)这种情况即可。


所以代码中将可能是质数的先提取出来。即当t>=5时将不是质数的先判断为False。


前半部分:



if t <= 1 or t == 4:
return False
elif t == 2 or t == 3:
return True
# 至此 先把t<5的情况全部讨论完,再看t>=5有规律的情况
elif t%6 != 1 and t%6 != 5:
# 这里采用!= 就是将可能为质数的提取出来,!= 的就一定不是质数
return False


那么接下来就是如何判断t=6x-1或者t=6x+1(x>=1)这两种形式到底是不是质数的问题了。首先我们采用方法二的大方向,这两种数如果不是质数,那么其必定会有一个因数不大于根号t,这样就找到了遍历时的右边界i = 根号t向上取整。那么i是从几开始,间隔又是几递增呢?直接搜会告诉你i从5开始,间隔是6,这是为什么?很多博客中说因为t=6x-1或者t=6x+1(x>=1),可是这个是t,又不是t的因数。那么为什么t的因数又只有6x-1或6x+1这两种形式呢?请看我细细道来。


* 首先,t=6x-1或者t=6x+1(x>=1)这两种形式的数的因数也只可能为6x-1或者6x+1(x>=1),因为其他数的形式6x,6x+2,6x+3,6x+4(x>=0)(这里如果取6x则x>=1)要么一定有最小因数2要么一定有最小因数3,因此都不可能是t=6x-1或者t=6x+1(x>=1)的因数(这个前面分析过了,因为其不管怎么拆都拆不出2和3).因此对于t=6x-1或者t=6x+1(x>=1)这两种形式的数的因数也只可能为6x-1或者6x+1(x>=1)的形式[这里相当于从5开始了,是因为1不算因数,2和3刚已经说了不可能为t的因数了,4(因为可以拆成2)因此不可能是t的因数了]。所以现在就知道i从5开始!且因为6x-1或者6x+1(x>=1)都有可能成为t的因数,因此每遍历一次i就要有两次判断!(分别针对6x-1和6x+1的,i从5开始即每次取i时就是在判断6x-1(x>=1),取i+2时就是在判断6x+1(x>=1)),即t%i ==0 or t%(i+2) ==0,一旦有能被整除的就是False。现在i递增是6就很容易理解了,第一轮x=1时6x-1=5;判断完后第二轮x=2时6x-1 = 6(x-1)-1+6,因此每次递增6就可以将6x-1(x>=1)刚好全部判断完。
* 没有然后了,已经结束,看不懂慢慢读多读几遍首先那一段就OK,不要着急。


方法三的完整代码:



import math
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

img
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值