經典演算法題每日演練 第七題 KMP演算法

2021-09-22 20:35:33 字數 2528 閱讀 5178

原文:

經典演算法題每日演練——第七題 kmp演算法

在大學的時候,應該在資料結構裡面都看過kmp演算法吧,不知道有多少老師對該演算法是一筆帶過的,至少我們以前是的,

確實kmp演算法還是有點饒人的,如果說紅黑樹是**級的,那麼kmp演算法比紅黑樹還要**,很抱歉,每次打kmp的時候,輸

入法總是提示「看**」三個字,嘿嘿,就叫「看**演算法」吧。

一:bf演算法

如果讓你寫字串的模式匹配,你可能會很快的寫出樸素的bf演算法,至少問題是解決了,我想大家很清楚的知道它的時間復

雜度為o(mn),原因很簡單,主串和模式串失配的時候,我們總是將模式串的第一位與主串的下乙個字元進行比較,所以複雜

度高在主串每次失配的時候都要回溯,圖我就省略了。

二:kmp演算法

剛才我們也說了,主串每次都要回溯,從而提高了時間複雜度,那麼能不能在「主串」和「模式串」失配的情況下,主串不回溯呢?

而是讓」模式串「向右滑動一定的距離,對上號後繼續進行下一輪的匹配,從而做到時間複雜度為o(m+n)呢?所以kmp演算法就是

用來處理這件事情的,下面我們看下簡單的例子。

通過這張圖,我們來討論下它的一般推理,假設主串為s,模式串為p,在si != pj的時候,我們可以看到滿足如下關係式

si-jsi-j+1...sn-1=p0p1..pj-1。那麼模式p應該向右滑動多少距離?也就是主串中的第i個字元應與模式串中的哪乙個字元進行比較?

假設應該與模式串中的第k的位置相比較,假如模式串中存在最大的字首真子串和字尾真子串,那麼有p0p1..pk-1=pj-kpj-k+1...pj-1.

這句話的意思也就是說,在模式p中,前k個字元與j個字元之前的k個字元相同,比如說:「abad」的最大字首真子串為「aba",最大

字尾真子串為「bad」,當然這裡是不相等,這裡的0next[j]來記錄失配時模式串應該用哪乙個字元於si進行比較。

設 next[j]=k。根據公式我們有

-1        當j=0時

next[j] =   max

0         其他情況

好,接下來的問題就是如何求出next[j],這個也就是kmp思想的核心,對於next[j]的求法,我們採用遞推法,現在我們知道了

next[j]=k,我們來求next[j+1]=?的問題?其實也就是兩種情況:

①:pk=pj 時  則p0p1...pk=pj-kpj-k+1...pj, 則我們知:

next[j+1]=k+1。

又因為next[j]=k,則

next[j+1]=next[j]+1。

②:pk!=pj 時  則p0p1...pk!=pj-kpj-k+1...pj,這種情況我們有點蛋疼,其實這裡我們又將模式串的匹配問題轉化為了上面我們提到

的」主串「和」模式串「中尋找next的問題,你可以理解成在模式串的字首串和字尾串中尋找next[j]的問題。現在我們的思路就是一定

要找到這個k2,使得pk2=pj,然後將k2代入①就可以了。

設   k2=next[k]。 則有p0p1...pk2-1=pj-k2pj-k2+1...pj-1。

若   pj=pk2,      則 next[j+1]=k2+1=next[k]+1。

若   pj!=pk2,      則可以繼續像上面遞迴的使用next,直到不存在k2為止。

好,下面我們上**,可能有點繞,不管你懂沒懂,反正我懂了。

1

using

system;

2using

system.collections.generic;

3using

system.linq;

4using

system.text;56

namespace

supportcenter.test725

26static

int kmp(string bigstr, string

smallstr)

2741

else

4245}46

47if (j ==smallstr.length)

48return i -smallstr.length;

4950

return -1;51

}5253///

54///

p0,p1....pk-1 (字首串)

55///

pj-k,pj-k+1....pj-1 (字尾串)

經典演算法題每日演練 第七題 KMP演算法

在大學的時候,應該在資料結構裡面都看過kmp演算法吧,不知道有多少老師對該演算法是一筆帶過的,至少我們以前是的,確實kmp演算法還是有點饒人的,如果說紅黑樹是 級的,那麼kmp演算法比紅黑樹還要 很抱歉,每次打kmp的時候,輸 入法總是提示 看毛片 三個字,嘿嘿,就叫 看毛片演算法 吧。一 bf演算...

經典演算法題每日演練 第七題 KMP演算法

在大學的時候,應該在資料結構裡面都看過kmp演算法吧,不知道有多少老師對該演算法是一筆帶過的,至少我們以前是的,確實kmp演算法還是有點饒人的,如果說紅黑樹是 級的,那麼kmp演算法比紅黑樹還要 很抱歉,每次打kmp的時候,輸 入法總是提示 看毛片 三個字,嘿嘿,就叫 看毛片演算法 吧。一 bf演算...

經典演算法題每日演練 第七題 KMP演算法

在大學的時候,應該在資料結構裡面都看過kmp演算法吧,不知道有多少老師對該演算法是一筆帶過的,至少我們以前是的,確實kmp演算法還是有點饒人的,如果說紅黑樹是 級的,那麼kmp演算法比紅黑樹還要 很抱歉,每次打kmp的時候,輸 入法總是提示 看 三個字,嘿嘿,就叫 看 演算法 吧。一 bf演算法 如...