此算法查找低于N
的所有素数var f = function(n){
var primes = [2]; //1
var flag; //1
for(var i=3; i<n; i+=2){ // ( from 3 to n-1 ) / 2
flag = true; //1
var startI = 0; // 1
for(var y=primes[startI]; y<=Math.sqrt(i); y=primes[++startI]){ // ???
if(i%y === 0) // 1
flag = false; // 1
}
if(flag) // 1
primes.push(i); // 1
}
return primes; // 1
}
到目前为止,我的分析已经完成,直到第一个循环,我不知道如何处理第二个总和(使用primes.length
和Math.sqrt
的那个)。
T(n)= 1 + 1 +总和((1 + 1 + ??奇怪的总和???),从i = 3到n -1)/ 2 + 1 + 1
我理解如何分析直到第二个嵌套循环,我怀疑它是围绕log(N)或类似的东西,但我想知道迭代的确切数量..
问题:
感谢任何帮助(链接到类似案例,书籍等)。
答案 0 :(得分:7)
内循环遍历sqrt(i)
以下所有素数的数组。
所以你必须计算该数组中的元素数量。对于素数数组,您必须使用π(i)
的近似值,即i
以下的素数。
您可以按x/ln(x)
或(更好)li(x)
来估算它们。更多details here。
对于分析,x/ln(x)
会更容易。
总得到(假设n = 2k+1
)
T(n) = T(n-2) + O(sqrt(n)/( (1/2)⋅ln(n) )) = O( Σi = 1,...,k 2⋅sqrt(2⋅i+1)/ln(2⋅i+1) )
你从内部for循环中得到递归公式,它遍历低于sqrt(n)
(近似为sqrt(n)/( (1/2)⋅ln(n) )
)的素数数组,以及你需要做的工作,由T(n-2)
代表。
也许你可以简化这个。我不想从你那里获得乐趣:)
提示:也许您可以使用积分来得到总和的近似值。但我认为没有“好”的方式来写下来。
如果你忘了1/ln(i)
- 部分,你可以看到
T(n) ∈ o(n3/2)
和T(n) ∈ ω(n)
。也许你可以做得更好。
正如@vib所提到的,你可以获得更严格的上限O(n3/2/ln(n))
。但请注意sqrt(n)/ln(n)
只是低于sqrt(n)
的素数的近似值。因此,您可以通过更好的近似获得更好的界限。由于此近似值未提供π(n)
的确切值,因此无法表示此算法在Θ(n3/2/ln(n))
中运行。