Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Eratosthenes算法的筛选效率_C++_Algorithm_Performance_Primes_Sieve Of Eratosthenes - Fatal编程技术网

C++ Eratosthenes算法的筛选效率

C++ Eratosthenes算法的筛选效率,c++,algorithm,performance,primes,sieve-of-eratosthenes,C++,Algorithm,Performance,Primes,Sieve Of Eratosthenes,我正在努力理解“埃拉托什尼筛”。这是我的算法(下面的代码),以及我无法理解的特性列表(按顺序) 为什么i*i比i*2更有效?是的,我可以理解它会减少迭代次数,因此效率更高,但它不会跳过一些数字吗(例如I=9是代码> i 的最小倍数,但尚未被消除。(把从1到100的数字写在纸上,用手执行算法查看。)至于i*i问题,它不会跳过任何内容,因为每个小于i^2的数字要么是素数,要么是素数因子小于i,因此在上一步中已经被标记。“根据我的理解,我们有2个完整迭代和1个部分迭代,因此O(n^2*logn)”复杂

我正在努力理解“埃拉托什尼筛”。这是我的算法(下面的代码),以及我无法理解的特性列表(按顺序)

  • 为什么
    i*i
    i*2
    更有效?是的,我可以理解它会减少迭代次数,因此效率更高,但它不会跳过一些数字吗(例如
    I=9
    跳过18 27 36…

  • 在维基百科上,我发现空间复杂性等于
    O(n)
    ,这是可以理解的;无论我们输入什么数字,它都会创建一个输入大小的数组,但这里的时间复杂性让事情变得混乱。我发现这个符号
    O(n(logn)(loglogn))
    ——那是什么?根据我的理解,我们有2个完整迭代和1个部分迭代,因此
    O(n^2*logn)
  • #包括
    使用名称空间std;
    int main(){
    不能改变大小;
    布尔Primersarr[arrSize];
    primesArr[0]=假;
    对于(inti=1;ij=81跳过18 27 36

    你指的是

    for (int j = i * i; j < arrSize; j += i)
    
    for(int j=i*i;j
    请注意,
    i*i
    是循环计数器
    j
    初始值。因此,
    j
    大于
    i*i
    的值都将被标记掉。我们从
    i*2
    跳到
    i*i
    的值在以前的迭代中已经被标记掉了。让我们考虑第一个t少数:

    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的倍数,20也是2的倍数,在我们最终到达25之前,它不是任何小于5的倍数


    时间复杂性是让人困惑的地方。我发现了这个符号O(n(logn)(loglogn))--那是什么?根据我的理解,我们有2个完整迭代和1个部分迭代,因此O(n^2*logn)

    您的分析得出了正确的结果,该算法是
    O(n^2*logn)
    。可以证明一个更严格的上界为
    O(n(logn)(loglogn))
    。注意
    O(n(logn)(loglogn))
    O(n^2*logn)
    的子集

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

    不,这不是因为
    i
    的较小倍数(例如,在您的情况下,在运行
    i=2
    i=3
    等的循环时,会覆盖18、27等)

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

    讨厌的符号
    O(n(logn)(loglogn))


    操作数为1/2+1/3+1/5+1/7…=n log log n

    如果你计算位运算,因为你处理的是n以下的数字,它们大约有logn位,这就是logn的因子,给出O(n logn logn)位运算。

    VLA不是C++中的好主意。大尺寸VLA完全是一个不同的问题。喜欢一个容器。在以前的迭代中已经消除了比 i>代码>的所有倍数的可能的重复。因此,<代码> i *i/c>是<>代码> i <代码>的最小倍数,但尚未被消除。(把从1到100的数字写在纸上,用手执行算法查看。)至于
    i*i
    问题,它不会跳过任何内容,因为每个小于
    i^2
    的数字要么是素数,要么是素数因子小于
    i
    ,因此在上一步中已经被标记。“根据我的理解,我们有2个完整迭代和1个部分迭代,因此O(n^2*logn)”复杂性很难计算,特别是在不常见的情况下,如何计算出O(n^2*logn)?
    for (int j = i * i; j < arrSize; j += i)