簡體   English   中英

這個c函數的復雜性是什么?

[英]What is the complexity of this c function

以下c函數的復雜性是多少?

double foo (int n) {
    int i;
    double sum;
    if (n==0) return 1.0;
    else {
        sum = 0.0;
        for (i =0; i<n; i++)
        sum +=foo(i);
        return sum;
    }
}

請不要只是發布復雜性,你可以幫助我理解如何去做。

編輯:這是一個在考試中提出的客觀問題,提供的選項是1.O(1)2.O(n)3.O(n!)4.O(n ^ n)

它是Θ(2 ^ n)(假設f是我們算法的運行時間):

f(n) = f(n-1) + f(n-2) + ... + 1
f(n-1) = f(n-2) + f(n-3) + ...
==> f(n) = 2*f(n-1), f(0) = 1
==> f(n) is in O(2^n)

實際上,如果我們忽略常量操作,那么確切的運行時間是2 n

同樣在你寫這個是考試的情況下,O(n!)和O(n ^ n)都是真的,並且它們中最接近Θ(2 ^ n)的答案是O(n!),但如果我是學生,我會標記他們兩個:)


關於O(n!)的說明:

for all n >= 1: n! = n(n-1)...*2*1 >= 2*2*2*...*2 = 2^(n-1) ==>
2 * n! >= 2^n ==> 2^n is in O(n!),
Also n! <= n^n for all n >= 1 so n! is in O(n^n)

So O(n!) in your question is nearest acceptable bound to Theta(2^n)

首先,它編碼很差:)

double foo (int n) {         // foo return a double, and takes an integer parameter
    int i;                   // declare an integer variable i, that is used as a counter below
    double sum;              // this is the value that is returned
    if (n==0) return 1.0;    // if someone called foo(0), this function returns 1.0
    else { // if n != 0
        sum = 0.0;           // set sum to 0
        for (i =0; i<n; i++) // recursively call this function n times, then add it to the result
        sum +=foo(i);
        return sum;          // return the result
    }
}

你正在調用foo()總共類似n ^ n(你將n舍入到最接近的整數)

例如:

foo(3)將被稱為3 ^ 3次。

祝你好運,祝聖誕快樂。

編輯:哎呀,剛剛糾正了一些事情。 為什么foo會返回雙倍? 它總是返回一個整數,而不是一個整數。

這將是一個更好的版本,微優化! :d

int foo(int n)
{
    if(n==0) return 1;
    else{
        int sum = 0;
        for(int i = 0; i < n; ++i)
        sum += foo(i);
        return sum;
    }
}

你可能會更清楚一點...... 發牢騷地抱怨道

<n = ?> : <return value> : <number of times called>
n = 0 : 1 : 1
n = 1 : 1 : 2
n = 2 : 2 : 4
n = 3 : 4 : 8
n = 4 : 8 : 16
n = 5 : 16 : 32
n = 6 : 32 : 64
n = 7 : 64 : 128
n = 8 : 128 : 256
n = 9 : 256 : 512
n = 10 : 512 : 1024

number_of_times_called = pow(2,n-1);

我們試着投入,我們呢?

使用此代碼:

 #include <iostream> double foo (int n) { int i; double sum; if (n==0) return 1.0; else { sum = 0.0; for (i =0; i<n; i++) sum +=foo(i); return sum; } } int main(int argc, char* argv[]) { for(int n = 0; 1; n++) { std::cout << "n = " << n << " : " << foo(n); std::cin.ignore(); } return(0); } 

我們得到:

 n = 0 : 1 n = 1 : 1 n = 2 : 2 n = 3 : 4 n = 4 : 8 n = 5 : 16 n = 6 : 32 n = 7 : 64 n = 8 : 128 n = 9 : 256 n = 10 : 512 

因此,它可以簡化為:

 double foo(int n) { return((double)pow(2, n)); } 

該功能由多個部分組成。

復雜性的第一位是if(n==0)return 1.0; 因為那只會產生一次運行。 那將是O(1)

下一部分是for(i=0; i<n; i++)循環。 因為它從0..n循環,所以它是O(n)

與遞歸相比,對於n每個數字,您再次運行該函數。 並在該函數中再次循環,以及下一個函數。 等等...

為了弄清楚它會是什么,我建議你在循環內部添加一個全局計數器,這樣你就可以看到它對某個數字執行了多少次。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM