【问题标题】:Why does this prime test work?为什么这个主要测试有效?
【发布时间】:2013-08-08 00:42:36
【问题描述】:

我找到了这个 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

【问题讨论】:

    标签: python algorithm primes


    【解决方案1】:

    让我们从函数代码的前四行开始:

    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。由于它们都是素数,如果n 等于其中一个,函数将返回True

    接下来,该函数测试n 是否可以被 2 或 3 整除,如果其中一个为真,则返回 False。这消除了非常多的情况,因为大于 2 的所有数字中有一半不是素数 - 它们可以被 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 &lt;= 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 可以被某物整除的情况,那么它一定是一个素数。

    【讨论】:

      【解决方案2】:

      除了 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) 的值。 而这个 sn-p 用于检查数字的平方根。

       while i * i <= n:
      

      此代码效率不高,因为集合 (6*n)+1 或 (6*n)-1 中有一些非素数。

      【讨论】:

        猜你喜欢
        • 2012-07-27
        • 2014-12-31
        • 1970-01-01
        • 2021-02-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-05
        相关资源
        最近更新 更多