我发现这个Python函数用于测试数字是否为素数;但是,我无法弄清楚算法是如何工作的。
def isprime(n):
"""Returns True if n is prime"""
if n == 2: return True
if n == 3: return True
if n % 2 == 0: return False
if n % 3 == 0: return False
i = 5
w = 2
while i * i <= n:
if n % i == 0:
return False
i += w
w = 6 - w
return True
答案 0 :(得分:10)
让我们从函数代码的前四行开始:
def isprime(n):
if n == 2: return True
if n == 3: return True
if n % 2 == 0: return False
if n % 3 == 0: return False
该函数首先测试n
是否等于2或3。由于它们都是素数,如果True
等于任何一个,函数将返回n
。
接下来,函数测试以查看n
是否可以被2或3整除,如果其中任何一个为真,则返回False
。这消除了极大量的情况,因为超过两个的所有数字中有一半不是素数 - 它们可以被2整除。同样的理由适用于3的可分性测试 - 它也消除了大量的情况。
该功能的棘手部分在接下来的几行中:
i = 5
w = 2
while i * i <= n:
if n % i == 0:
return False
i += w
w = 6 - w
return True
首先,i
(或索引)设置为5. 2和3已经过测试,4用n % 2
测试。所以,从5开始是有意义的。
接下来,w
设置为2. w
似乎是“增量”。到目前为止,该函数已经测试了所有偶数(n % 2
),因此增加2会更快。
该函数进入while
循环,条件为i * i <= n
。使用此测试是因为every composite number has a proper factor less than or equal to its square root。在平方根之后测试数字是没有意义的,因为它会是多余的。
在while
循环中,如果n
可被i
整除,则它不是素数,函数返回False
。如果不是,则i
会增加“增量”w
,这又会更快。
也许功能中最棘手的部分在于倒数第二行:w = 6 - w
。这导致“增量器”w
在每次通过循环时在值2和4之间切换。在w
为4的情况下,我们绕过一个可被3整除的数字。这比保持在2的速度快,因为该函数已经通过2和3测试了可除性。
最后,函数返回True
。如果函数未检测到n
可被某事整除的任何情况,则它必须是素数。
答案 1 :(得分:3)
除了2和3之外,所有素数都可以表示使用(6 * n)+1或(6 * n)-1,其中n是0到无穷大。 这个程序正在按照这个想法运作。 使用此行,检查号码可以被2或3
整除 if n % 2 == 0: return False
if n % 3 == 0: return False
然后我们需要检查数字是否可以被除3之外的其他素数整除。
i = 5
w = 2
while i * i <= n:
if n % i == 0:
return False
i += w
w = 6 - w
下一个素数是5.因此i的初始值设为5。 要获得集合中的所有数字(6 * n)+1或(6 * n)-1,或者更改w(2,4)的值。 而这个片段用于检查数字的平方根。
while i * i <= n:
此代码效率不高,因为集合中的一些非素数(6 * n)+1或(6 * n)-1。