【发布时间】:2018-07-03 19:47:18
【问题描述】:
我正在尝试理解“埃拉托色尼筛法”。这是我的算法(下面的代码),以及我无法理解的功能列表(按顺序)。
- 为什么
i * i比i * 2更高效?是的,我可以理解它会减少迭代次数,因此效率更高,但它不会跳过一些数字(例如i = 9=>j = 81skips 18 27 36 ...)吗? - 在维基百科上,我发现空间复杂度等于
O(n),这是可以理解的;无论我们输入什么数字,它都会创建一个输入大小的数组,但是这里的时间复杂度是让事情变得混乱的地方。我找到了这个符号O(n(logn)(loglogn))——那是什么?据我了解,我们有 2 次完整迭代和 1 次部分迭代,因此O(n^2 * logn)。
#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;
}
【问题讨论】:
-
VLA 在 C++ 中不是一个好主意。大尺寸 VLA 完全是一个不同的问题。更喜欢容器。
-
所有小于
i的倍数在之前的迭代中已经被消除了。因此,i * i是尚未消除的i的最小倍数。 (把1到100的数字写在纸上,用手执行算法看看。) -
至于
i * i问题,它不会跳过任何内容,因为每个小于i^2的数字要么是素数,要么具有小于i的素数,因此已经被标记在上一步。 -
"根据我的理解,我们有 2 次完整迭代和 1 次部分迭代,因此 O(n^2 * logn)" 复杂度很难计算,尤其是在不平凡的情况下,你怎么想出来与 O(n^2*logn)?
标签: c++ algorithm performance primes sieve-of-eratosthenes