【问题标题】:why the iteration is done by i+6 every time and why the condition is i*i<=n for this prime testing function?为什么每次迭代都由 i+6 完成,为什么这个主要测试函数的条件是 i*i<=n?
【发布时间】:2019-03-05 19:34:31
【问题描述】:

https://www.geeksforgeeks.org/primality-test-set-1-introduction-and-school-method/

//一个优化的基于学校方法的C++程序检查 // 如果一个数是素数

#include <bits/stdc++.h> 
using namespace std; 

bool isPrime(int n) 
{ 
    // Corner cases 
    if (n <= 1)  return false; 
    if (n <= 3)  return true; 

    // This is checked so that we can skip  
    // middle five numbers in below loop 
    if (n%2 == 0 || n%3 == 0) return false; 

    for (int i=5; i*i<=n; i=i+6) 
        if (n%i == 0 || n%(i+2) == 0) 
           return false; 

    return true; 
}

【问题讨论】:

  • 该链接解释了为什么它以 6 为增量。我将留给您回答:一个数字的因子可以大于它的平方根吗?

标签: c++ primality-test


【解决方案1】:

当您搜索质数时,您可以遍历 2 和您的数字之间的所有数字,看看它们是否能除以您的数字。

for (int i=2; i < n; i=i+1) 
    if (n%i == 0)
       return false; 

但这会检查很多您不需要的数字。
第一个观察结果(优化)是任何 2 的倍数(偶数)已经通过简单地除以 2 检查一次来检查。

所以现在我们检查 2,然后跳过所有其他偶数字符。

if (n%2 == 0 ) return false;

for (int i=3; i < n; i=i+2) 
    if (n%i == 0)
       return false; 

下一个观察结果(优化)是您可以为三个人做几乎相同的事情。所以第一个测试涵盖了 2 和 3 的所有组合。现在在循环中,您跳过每 6 个数字 (2*3) 并进行一些测试,以覆盖所有不是 2 或 3 倍数的数字。

if (n%2 == 0 || n%3 == 0) return false; 

for (int i=5; i<n; i=i+6) 
    if (n%i == 0 || n%(i+2) == 0) 
       return false; 

所以这只是一种优化,意味着您不必尝试每个数字。

我们做出的下一个观察是,您不需要尝试大于 n 的平方根的数字(这些永远不会被 n 整除)。因此,您可以将循环限制为 i*i &lt; n,因为 i*isqrt(n) 快。

if (n%2 == 0 || n%3 == 0) return false; 

for (int i=5; i*i<=n; i=i+6) 
    if (n%i == 0 || n%(i+2) == 0) 
       return false; 

虽然我个人会在循环中执行一次sqrt() 而不是i*i。但对于较小的 n 值,这可能会更慢。

【讨论】:

    【解决方案2】:

    任何复合数都至少有一个因子小于或等于它的平方根。为什么?因为如果它只有一个因子(除了它自己或一个),那将等于它的平方根。如果它有两个或更多,最小的一个必须小于它的平方根。所以不需要检查大于平方根的数字——如果它不是素数,我们就已经找到了一个因数。

    代码会提前检查 2 或 3 作为一个因素。之后,我们只需要检查不是 2 或 3 的倍数的因子。所以在我们检查了 5 和 7 之后,我们不需要检查 6、8、9 或 10。所以在每六个数字中,我们只需要检查两个不是 2 或 3 的倍数的数字。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-25
      • 2023-03-17
      • 2020-05-24
      • 1970-01-01
      • 2022-07-13
      • 2020-11-11
      相关资源
      最近更新 更多