这个C ++函数的时间复杂度是多少?

时间:2011-04-18 15:04:58

标签: c++ time-complexity

我写了一个函数来显示主要数字和特定数字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;
}

结果可能在某些地方重复,但这不是重大问题。我不知道如何计算这个递归函数的时间复杂度。

3 个答案:

答案 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。在这种情况下,您会发现ij都是主要的除数。

答案 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)

我试图翻译(到递归关系)并以正式的方式解决你的算法,如下所示:

enter image description here

增长的顺序是非多项式,这是一个要避免的算法!