Eratosthenes算法的筛选效率

时间:2018-01-24 17:06:57

标签: c++ algorithm performance primes sieve-of-eratosthenes

我正在努力了解Eratosthenes" Sieve of Eratosthenes"。这是我的算法(下面的代码),以及我无法理解的功能列表(按顺序)。

  1. 为什么i * ii * 2效率更高?是的,我可以理解它会减少迭代次数,因此效率更高,但是它不会跳过一些数字(例如i = 9 => j = 81 skips 18 27 36 ...) ?
  2. 在维基百科上,我发现空间复杂度等于O(n),这是可以理解的;无论我们输入什么数字,它都会创建一个输入大小的数组,但这里的时间复杂性让事情变得混乱。我找到了这个符号O(n(logn)(loglogn)) - 这是什么?根据我的理解,我们有2次完整迭代和1次部分迭代,因此O(n^2 * logn)
  3. #include <iostream>
    using namespace std;
    
    int main() {
      cout << "Enter number:" << endl;
    
      int arrSize;
      cin >> arrSize;
    
      bool primesArr[arrSize];
      primesArr[0] = false;
      for (int i = 1; i < arrSize; i++) primesArr[i] = true;
    
      for (int i = 2; i < arrSize; i++)
    
        if (primesArr[i - 1]) {
          cout << i << endl;
       /* for (int j = i * 2; j < arrSize; j += i) less efficient */
          for (int j = i * i; j < arrSize; j += i)
            primesArr[j - 1] = false;
        }
    
      return 0;
    }
    

2 个答案:

答案 0 :(得分:6)

  

为什么我*我比i * 2更有效率?是的,我可以理解这将是更少的迭代,因此效率更高,但是它不会跳过一些数字(例如i = 9 =&gt; j = 81 skip 18 27 36 ......)?

你指的是

for (int j = i * i; j < arrSize; j += i)

请注意,i * i是循环计数器j初始值。因此j大于i * i的值都会被标记出来。我们在i * 2i * i之间跳过的值已经在之前的迭代中标记过了。让我们考虑前几个:

i == 2时,我们标记所有2的倍数(2,4,6,8等)。当i == 3时,如果我们开始j = 3 * 2 = 6,那么我们会在达到9,12,15等之前再次标记6.由于6是2的倍数并且已经标记为关闭,我们可以直接跳到3 * 3 == 9

当我们到达i == 5并且如果我们从j == 5 * 2 == 10开始,那么我们将标记10,这已经被处理,因为它是2的倍数,15是3的倍数在我们最终达到25之前,它也是2的倍数,这不是任何小于5的引物的倍数。

  这里的时间复杂性让事情变得混乱。我发现这个符号O(n(logn)(loglogn)) - 这是什么?根据我的理解,我们有2次完整迭代和1次部分迭代,因此O(n ^ 2 * logn)。

您的分析得出的结果是此算法为O(n^2 * logn)A more detailed analysis可以证明O(n(logn)(loglogn))更严格的上限。请注意,O(n(logn)(loglogn))O(n^2 * logn)的一个子集。

答案 1 :(得分:3)

  

为什么我*我比i * 2更有效率?它没有跳过一些数字吗?

不,它不是因为i的较小倍数(例如,在i = 2i = 3等运行循环时,您的案例中包括18,27等等)

每个数字都可以表示为唯一的素数因子分解。如果i是素数,则i大于i且小于i * i的任意倍数将是小于i的一个或多个素数的倍数。

  

令人讨厌的表示法O(n(logn)(loglogn))

来自this answer
操作次数为1/2 + 1/3 + 1/5 + 1/7 ... = n log log n
如果计算位操作,由于您处理的数字最多为n,它们有大约log n位,这是log n的因子进入的位置,给出O(n log n log log n)位操作。