【发布时间】:2014-09-13 14:35:58
【问题描述】:
我用C写了一个类似的函数,并且能够达到与java不同的所需结果。 下面是代码,它递归地检查一个数字是否是素数。 编译说,我缺少返回声明。 如果素数是 x,则要检查的数字。变量 i 是除数。(ie) x/2, (x/2)-1,...0。
public int primes(int x, int i)
{
if(i==0)
return 1;
if(x%i==0)
return 0;
else
primes(x, i-1);
}
如果我必须打印前 1000 个素数,这段代码的复杂度是多少?
【问题讨论】:
-
对于复杂性,在最坏的情况下,
i一直下降到 0,所以如果i从x/2开始,它大约是 O(x)。但这将摊销到更小的东西,因为显然不是每个数字都是素数(en.wikipedia.org/wiki/Prime_number_theorem)。对于仅仅 1000 个素数,我怀疑无论如何它会花费很长时间。 -
@Ben 不,它不会摊销到任何更小的东西,因为测试是以错误的顺序完成的。 n=1000 个素数表示要测试的 ~ N=8000 个数字,通过 O(N^2) 算法;不要仅仅因为 n=1000 看起来很小(你确实说过“无论如何”......)而确定它会运行得很快 - 它的复杂性非常糟糕(参见例如这个 Haskell test entry 与显示的等效算法〜 N^2.2 , ~ n^2.5 运行时行为。
-
我的意思是 OP 的
primes是 O(x)(或 O(n) 或其他)。所以可以肯定的是,如果他循环它是 O(n^2),但它不会采取绝对最坏的情况,因为 OP 已经声明他从x/2开始i,所以偶数立即失败。然后找到 1000 个素数x只需要 7919,因此对于大多数数字来说,素数不会递归很远。 -
@Ben 他们确实谈到了寻找前 1000 个素数。我给你证据表明它比N^2差。
-
算法is ~ n^2.5的empirical orders of growth,产生了n个素数。