KMP演算法的效率分析

2021-07-23 20:19:22 字數 1721 閱讀 6536

上一節,我們研究了kmp演算法的實現原理,這節,我們從分析的角度看看kmp演算法的時間複雜度和它的正確性。

我們先看計算匹配字串最長字尾陣列的的函式:

private

intgetlongestsuffix(int s) throws exception

if (pi[s] != -1)

pi[s] = 0;

int k = getlongestsuffix(s-1);

do if (k > 0)

} while (k > 0);

return pi[s];

}

要確定該函式的時間複雜度是o(m),(其中m是匹配字串的長度),不是一件容易的事。一是該函式中有遞迴呼叫,同時函式中又有while迴圈,所以確保該函式的時間複雜度是線性的,需要一定的分析。

getlongestsuffix第一次呼叫時,傳入的引數是p.length(p是匹配字串), 也就是該函式呼叫是,輸入引數最大也就是m.

do.. while 迴圈的條件是變數k大於0,並且在迴圈中,要進行遞迴呼叫的話,同樣需要k > 0. 一旦k等於0,那麼do…while迴圈和遞迴呼叫將會停止。

如果if(k>0) 條件成立,進入遞迴呼叫,我們可以確定,返回的k值是遞減的,一旦遞減到0,那麼遞迴呼叫和do..while迴圈都會停止進行。getlongestsuffix返回的是pi數值中的元素值,也就是說,k的數值跟pi陣列中某乙個元素是對應的。

一旦k == 0, 那麼下次do..while迴圈能夠迴圈兩次以上,或者說下次能夠再次滿足if(k>0) 以便進行遞迴呼叫的話,判斷if (p.charat(k) == p.charat(s - 1)) 必須滿足,這樣k值才重新獲得乙個大於0的值。這就意味著do…while迴圈的次數以及遞迴呼叫的次數之和,小於if (p.charat(k) == p.charat(s - 1)) 成立的次數。而該條件成立的次數最多不超過匹配字串的字元個數,也就是m, 並且一旦成立,函式裡面返回,這也意味著,do..while迴圈的總次數和遞迴呼叫的總次數之和不會大於m,因此這個函式的時間複雜度就是o(m).

我們再看匹配函式match的實現:

public

intmatch(string t)

if (p.charat(q) == t.charat(i))

if (q == m)

}return -1;

}

在match的實現中,有乙個迴圈間套,外層迴圈for的迴圈次數是匹配文字t的長度,如果我們能確保,for裡面的while迴圈總次數為o(t.length), 那麼就算有兩個迴圈間套,那麼迴圈的總次數也就是t.length.

要想進入while迴圈,必須滿足乙個條件是q>0, 當進入迴圈後,執行語句 q = pi[i];

這條語句的執行,必定會使得q值變小,while每迴圈一次,q值就減少,如果q減少到0後,while迴圈就不會再進行了。

那麼什麼時候,while迴圈可以進行呢,顯然至少要q>0滿足,當q減少到0之後,要想重新大於0,必須執行語句:

if (p.charat(q) == t.charat(i))
上面的語句是間套在for迴圈裡面的,for迴圈最多進行t.length次,也就是匹配文字的長度,由此說來,q由0到大於0的次數最多只有t.length次,這就意味著while迴圈最多也只能進行t.length次。

這就保證了match函式的複雜度是o(t.length).

資料結構 關於KMP演算法的效率分析

通常的kmp演算法可以描述如下,不知道的可以查相關資料。從s的pos位置開始尋找字串t int index kmp string s,string t,int pos else j next j i不變 不回溯 j跳動 if j t.length return i t.length 匹配成功 els...

KMP演算法分析

根據博主july的所載,記錄個人理解心得 紅色部分為個人理解 1.kmp演算法流程 假設現在文字串s匹配到 i 位置,模式串p匹配到 j 位置 1.如果j 1,或者當前字元匹配成功 即s i p j 都令i j 繼續匹配下乙個字元 當s i p j 時,說明模式串j前面的字元都與文字串i前面對應的字...

演算法分析 演算法的漸進效率分析

一般用於界定函式集合的上界,漸進表示式o g n 的含義就是,c為正常數,函式集合o中的元素的最大值不會超過c.g n f n o g n 的含義是,函式f n 的屬於集合o g n 因為函式集合o中的最大值為c.g n 所以f n 的最大值為c.g n 由於只是漸進的上界,所以當函式g n 的階數...