生成前n个素数数组的时间复杂度?

时间:2018-07-15 20:20:24

标签: javascript math time-complexity big-o primes

对于采用整数n并返回前n个素数的数组的函数,我们有:

function nPrimes(n) {
    let primes = [];
    for(let i = 3; primes.length < n - 1; i += 2) {
        if (primes.every(prime => i % prime !== 0)) {
            primes.push(i);
        }
    }
    primes.unshift(2);
    return primes;
}

我不确定此算法的复杂程度。看来至少是二次的,因为every调用给运行时复杂度增加了一个n,其中n是给定迭代中素数数组的大小。最后的unshift添加了一个n,但这是无关紧要的,因为它会因前导系数而相形见f。

后续工作是,有没有更有效的方法来生成这样的数组?

1 个答案:

答案 0 :(得分:0)

此计算非常艰巨。

外部循环执行n次,并为从every到第3个素数的所有奇数调用n构造。

如果every构造确实测试了列表中的所有素数,则总工作量将与k.(P[k+1]-P[k]) = k.G[k]的总和成比例,其中P[k]k -第一个素数和G[k]之间的距离直到下一个素数(找到第k个素数时,列表中包含k个元素,并进行测试直到下一个素数)。

根据素数定理,我们知道“平均”间隙长度约为log P[k],本身约为log(k log k) = log k + log log k。然后求和得出O(n.log n)

现在,如果every构造在满足错误条件时立即停止,则可以降低成本。实际上,搜索将在被测数字的第一个素数处停止,总工作量将与所有P[n] ~ n log n之前的所有奇数的第一个素数的索引之和成比例。

从网络搜索看来,整数的第一个质数因子的分布遵循1 / P[k] log P[k]中第k个质数,即1 / k.log k.log(k.log k)的定律,我们需要使用m对所有整数k ~ m / log m求和。既不严格也不容易。