簡體   English   中英

如何計算以下function的時間復雜度?

[英]How do I calculate the time complexity of the following function?

這是一個遞歸的 function。 它遍歷字符串的 map ( multimap<string, string> graph )。 檢查itr -> second ( s_tmp ) 如果s_tmp等於所需的字符串 ( Exp ),打印它 ( itr -> first ) 並為該itr -> first再次執行 function 。

string findOriginalExp(string Exp){
    cout<<"*****findOriginalExp Function*****"<<endl;
    string str;
    if(graph.empty()){
        str ="map is empty";
    }else{
        for(auto itr=graph.begin();itr!=graph.end();itr++){
        string s_tmp = itr->second;
        string f_tmp = itr->first;
        string nll = "null";
        //s_tmp.compare(Exp) == 0
        if(s_tmp == Exp){
            if(f_tmp.compare(nll) == 0){
            cout<< Exp <<" :is original experience.";
            return Exp;
            }else{
                return findOriginalExp(itr->first);

            }
        }else{
            str="No element is equal to Exp.";
        }
     }

    }
    return str;
    }

沒有停止的規則,它似乎是完全隨機的。 這個function的時間復雜度是怎么計算的?

我不打算分析您的 function 而是嘗試以更一般的方式回答。 似乎您正在為 function 的復雜性尋找一個簡單的表達式,例如O(n)O(n^2) 然而,復雜性並不總是那么容易估計。

在您的情況下,它在很大程度上取決於graph的內容以及用戶作為參數傳遞的內容。

作為一個類比,考慮這個 function:

int foo(int x){
    if (x == 0) return x;
    if (x == 42) return foo(42);        
    if (x > 0) return foo(x-1);            
    return foo(x/2);
}

在最壞的情況下,它永遠不會返回給調用者。 如果我們忽略x >= 42 ,那么最壞情況的復雜度是O(n) 僅此一項作為對用戶的信息並沒有那么有用。 作為用戶,我真正需要知道的是:

  • 永遠不要用x >= 42來調用它。
  • O(1)如果x==0
  • O(x)如果x>0
  • O(ln(x))如果x < 0

現在嘗試對您的 function 進行類似的考慮。 簡單的情況是Exp不在graph中,在這種情況下沒有遞歸。 我幾乎可以肯定,對於“正確”輸入,您的 function 可以永遠不會返回。 找出這些案例並記錄下來。 在這兩者之間,您有一些案例在有限數量的步驟后返回。 如果您完全不知道如何通過分析來掌握它們,您可以隨時設置基准和衡量標准。 測量輸入大小10501001000 .. 的運行時間應該足以區分線性、二次和對數相關性。

PS:只是一個提示:不要忘記代碼實際上應該做什么以及解決該問題所需的時間復雜度(通常以抽象的方式討論這個問題比深入研究代碼更容易)。 在上面的愚蠢示例中,整個 function 可以替換為等效的int foo(int){ return 0; } int foo(int){ return 0; }這顯然具有恆定的復雜性,不需要比這更復雜。

這個 function 采用一個有向圖和該圖中的一個頂點,並向后追逐進入它的邊以找到一個沒有邊指向它的頂點。 查找任何給定頂點“后面”的頂點的操作需要O(n)字符串比較, n是圖中 k/v 對的數量(這是for循環)。 它這樣做了m次,其中m是它必須遵循的路徑的長度(它通過遞歸完成)。 因此,它具有時間復雜度O(m * n)的字符串比較, n是 k/v 對的數量, m是路徑的長度。

請注意,對於您看到的用代碼編寫的一些 function,通常沒有“時間復雜度”之類的東西。 您必須定義要用來描述時間的變量,以及要用來測量時間的操作。 例如,如果我們想純粹根據 k/ n對的數量來寫這個,你會遇到問題,因為如果圖形包含一個適當放置的循環,function不會終止! 如果您進一步將圖約束為無環圖,則任何路徑的最大長度受m < n約束,然后您還可以得到此 function 對具有n條邊的無環圖進行O(n^2)字符串比較。

您應該使用遞歸關系來近似遞歸調用的控制流。 自從我上離散數學的大學課程以來已經有 30 年了,但通常你確實喜歡偽代碼,足以看到有多少調用。 在某些情況下,僅計算右側最長條件下有多少是有用的,但您通常需要重新插入一個展開式,並從中推導出多項式或冪關系。

暫無
暫無

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

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