为什么这个主要测试工作?

时间:2013-08-08 00:42:37

标签: python algorithm primes

我发现这个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

2 个答案:

答案 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。