我写了一个函数来显示主要数字和特定数字n的因素。
bool PrimeFactor(int n){
int count = 0;// count divisors
for (int i = 2 ; i < n; i++){
if ( n % i == 0 ){
if ( PrimeFactor(i)){
cout << i << endl;
}
count ++;
}
}
if (count > 0)//not prime
return false;
return true;
}
结果可能在某些地方重复,但这不是重大问题。我不知道如何计算这个递归函数的时间复杂度。
答案 0 :(得分:3)
这基本上是Ben Voigt答案的更加扩展版本。
正如Ben Voigt所说,没有条件的版本是O(n)
,这应该是直截了当的。
现在,带有条件的版本将在if
语句中执行递归,其次数等于n的除数(= value of the divisor function for n = d(n)
)。< / p>
下限inf d(n) = 2
,因为对于每个素数,这都是正确的并且有无数多个素数,所以无论你做多大n
,你总能找到一个d(n) = 2
。 1}}。这意味着对于素数,您的函数将递归0次并且具有复杂度O(n)
。
上限更复杂(我需要咖啡),所以让我们暂时忽略它并计算平均复杂度。 d(n) = O(log n)
的平均复杂度,正如Ben Voigt所述,原始函数的平均复杂度为O(n log n loglog n ...)
。更详细:你有for循环,O(n)
,在这个for循环中,你将平均递归d(n) = O(log n)
次。现在再次输入该函数并递归O(log (log n))
次等等。
另请注意DarkDust&amp;提出的问题评论。杰夫福斯特。它也不会以你想要的方式运作。此外,检查偶数除n
是否无用,因为偶数永远不会是素数(当然除了2)。由于递归,您将在递归调用期间输入内部if
(带有cout
的那个),因此您获得的输出将不是您想要的(我假设是独特的) n)的主要除数。
节省时间的另一种方法是仅测试floor(sqrt(n))
。如果数字i
完全划分n
,请检查商j = n / i
是否也是素数。例如。对于n = 6
,您最多可以测试floor(sqrt(6)) = 2
。然后你会发现i = 2
是一个除数,你检查j = 6 / 2 = 3
。在这种情况下,您会发现i
和j
都是主要的除数。
答案 1 :(得分:2)
这种简化不会比原始时间更少,并且具有复杂性O(n!)
。所以这是一个上限。
bool PrimeFactor(int n)
{
for (int i = 2 ; i < n; i++) PrimeFactor(i);
}
我认为原作的复杂性是O(n log n loglog n ...)
。
答案 2 :(得分:0)
我试图翻译(到递归关系)并以正式的方式解决你的算法,如下所示:
增长的顺序是非多项式,这是一个要避免的算法!