簡體   English   中英

內部循環遞歸函數的時間復雜度分析

[英]Time complexity analysis of function with recursion inside loop

我正在嘗試分析以下功能的時間復雜度。 此函數用於檢查一個字符串是否由其他字符串組成。

set<string> s; // s has been initialized and stores all the strings
bool fun(string word) {
    int len = word.size();

    // something else that can also return true or false with O(1) complexity

    for (int i=1; i<=len; ++i) {
       string prefix = word.substr(0,i);
       string suffix = word.substr(i);
       if (prefix in s && fun(suffix))
           return true;
       else
           return false;
    }
}

我認為時間復雜度為O(n) ,其中n是單詞的長度(我對嗎?)。 但是由於遞歸位於循環內部,所以我不知道如何證明這一點。

編輯:

此代碼不是正確的C++代碼(例如prefix in s )。 我只是展示了此函數的概念,並想知道如何分析其時間復雜度

分析此問題的方法是通過根據輸入的長度和前綴在s的(未知)概率建立遞歸關系。 我們假設前綴在s中的概率由前綴長度L的某個函數pr(L)給出。 令復雜度(操作數)由T(len)給出。

如果len == 0( word是空字符串),則T =1。(該函數在循環后缺少最后一個return語句,但是我們假設實際代碼只是該構思的草圖,而不是內容的縮寫)實際執行)。

對於每次循環迭代,用T(len; i)表示循環體的復雜度。 如果前綴不在s ,則主體具有恆定的復雜度(T(len; i)= 1)。 該事件的概率為1-pr(i)。

如果前綴在s ,則該函數根據對fun(suffix)的遞歸調用返回truefalse ,其復雜度為T(len-i)。 此事件的概率為pr(i)。

因此,對於i每個值,循環體的復雜度為:

T(len; i)= 1 *(1- pr(i))+ T(len-i)* pr(i)

最后(這取決於預期的邏輯,而不是發布的代碼),我們有

T(len)=總和i = 1 ... len (T(len; i))

為簡單起見,讓我們將pr(i)視為值為0.5的常數函數。 然后,T(len)的遞歸關系為(直到一個常數因子,這對於O()計算而言並不重要):

T(len)=總和i = 1 ... len (1 + T(len-i))= len +總和i = 0 ... len-1 (T(i))

如上所述,邊界條件為T(0)=1。這可以通過標准遞歸函數方法解決。 讓我們看一下前幾個術語:

len   T(len)
0     1
1     1 + 1 = 2
2     2 + 2 + 1 = 5
3     3 + (4 + 2 + 1) = 11
4     4 + (11 + 5 + 2 + 1) = 23
5     5 + (23 + 11 + 5 + 2 + 1) = 47

模式顯然是T(len)= 2 * T(len-1)+1。這對應於指數復雜度:

T(n)= O(2 n

當然,此結果取決於我們對pr(i)所做的假設。 (例如,如果所有i的pr(i)= 0,則T(n)= O(1)。如果pr(i)具有最大前綴長度-pr(i)=對於所有i> 0>對於某些M,M。)pr(i)獨立於i的假設可能是不現實的,但這實際上取決於s的填充方式。

假設您已解決其他人指出的錯誤,則i值是要分割字符串的位置(每個i是最左側的分割點,然后遞歸i右側的所有內容)。 這意味着,如果要平移遞歸,則要查看多達n-1不同的拆分點,並詢問每個子字符串是否為有效單詞。 如果word的開頭沒有您集合中的很多元素,那么事情就可以了,從那時起您可以跳過遞歸。 但是在最壞的情況下, prefix in s始終為true,並且您嘗試n-1分割點的所有可能子集。 這給出了2^{n-1}不同的拆分集,乘以每個此類拆分集的長度。

暫無
暫無

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

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