What is the time complexity of this C++ function?

走远了吗. 提交于 2020-01-06 15:17:07

问题


I have written a function to show both number who is prime and factor of a specific number 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;
}

The result may be duplicated in some place, but that's not the big matter. I don't know how to calculate the time complexity of this recursive func .


回答1:


This is basically a more extended version of Ben Voigt answer.

As Ben Voigt said, the version without the conditional is O(n), this should be straightforward.

Now, the version with the conditional will execute the recursion inside the if statement a number of times equal to the number of divisors of n (= value of the divisor function for n = d(n)).

The lower limit inf d(n) = 2, since for every prime, this will be true and there are infinitely many primes, so no matter how big you make n, you can always find one for which d(n) = 2. This means that for primes, your function will recurse 0 times and it has complexity O(n).

The upper limit is more complicated (and I need coffee), so lets skip that for a moment and calculate the average complexity. The average complexity of d(n) = O(log n), so, as stated by Ben Voigt, the original function will have an average complexity of O(n log n loglog n ...). More in detail: you have the for loop, which is O(n), in this for loop you will recurse an average of d(n) = O(log n) times. Now you enter the function again and recurse O(log (log n)) times, etc, etc.

Also note the comments to your question by DarkDust & Jeff Forster. It will not function the way you want it too. Furthermore, checking if even numbers divide n is useless, since even numbers will never be primes (except for 2 of course). Due to the recursion, you will enter the inner if (the one with cout) during recursive calls, so the output you get, will not be what you want (which I'm assuming is the distinct prime divisors of n).

Another way to save time is by only testing up to floor(sqrt(n)). If a number i divides n exactly, check if the quotient j = n / i is also a prime number. E.g. for n = 6, you'd test up to floor(sqrt(6)) = 2. Then you find that i = 2 is a divisor and you check j = 6 / 2 = 3. You find that both i and j are prime divisors in this case.




回答2:


This simplification will recurse no fewer times than the original, and it has complexity O(n!). So that's an upper bound.

bool PrimeFactor(int n)
{
    for (int i = 2 ; i < n; i++) PrimeFactor(i);
}

I think the complexity of the original is O(n log n loglog n ...).




回答3:


I have attempted to translate (to a recurrence relation) and solve your algorithm in a formal way, like the following:

The order of growth is non polynomial, which is an algorithm to avoid!



来源:https://stackoverflow.com/questions/5704910/what-is-the-time-complexity-of-this-c-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!