記錄KMP演算法,記錄其經典之處。。。

2021-04-18 16:10:34 字數 1629 閱讀 6930

離開學校已經多年了,早已經不再撫弄那些陳舊的書籍。

週末,深圳的天氣陰沉,老天這段時間總是很樂意顯擺,動不動就給深圳人民來次幾十年一遇的暴雨,似乎要把一年的雨水全部在這些天下完似的。

所以呆在家裡面看電視,上網,實在也無聊。隨手翻開大學時候的(資料結構,還留著啊,當初剛出來的時候總沒有底氣,總希望能夠隨時充電用)。看到了字串的模式匹配一章。突然發現kmp演算法是如此的經典。故記之。。。

在提kmp的經典之前,首先要提基本的模式匹配演算法:

所謂模式匹配,簡單點說就是對兩字串進行匹配,找出乙個字串在另乙個字串中的位置。

基本的模式匹配是這樣的:

假設有字串

s=s1s2......sn(由於為了演算法效率的需要,所以一般都把s[0]儲存s的長度)

p=p1p2......pm(同上)

其中(m

所以演算法要點如下:

假設從s中i點開始掃瞄(也就是從s[i]開始,此時用乙個變數k=i),順序比較s[i]和p[1],s[i+1]和p[2]。這樣,當p進行到第j個字元也就是p[j]的時候,發現s[i+j-1]和p[j]不匹配,那麼需要把s的指標i回朔到s起始的下乙個字元也就是k+1繼續比較。

如圖:

以上就是模式匹配的基本演算法,這種演算法對於大多數的匹配來說基本是o(n+m)的時間複雜度。

但是對於如下的字串:

s=0000000000000000000000000000001

p=000001

這種字串來說,每次匹配失敗都是在p到最後乙個字元也就是j=m的時候,此時s的指標又必須回朔,導致大量的匹配。此時的時間複雜度是o(n*m)。

所以基本演算法的時間複雜度是o(n*m)。當然了,對於大多數的匹配是不會有這麼高的時間複雜度的,所以這種演算法現在也在廣泛使用,因為簡單。

為了解決上述的問題,kmp演算法被發現。

kmp演算法的思想如下。匹配過程中,出現不匹配時,s的指標不進行回朔(原地不動),將p盡可能地向後移動一定的距離,再進行匹配。

如圖:

從上圖中我們看到,當s移動到i,p到j的時候失配。這時候i不回朔,而只是將p向前移動盡可能的距離,繼續比較。

假設,p向右移動一定距離後,第k個字元p[k]和s[i]進行比較。

此時如上圖,當p[j]和s[i]失配後,i不動,將p前移到k,讓p[k]和s[i]繼續匹配。現在的關鍵是k的值是多少?

通過上圖,我們發現,因為黃色部分表示已經匹配了的結果(因為是到了s[i]和p[j]的時候才失配,所以si-j+1si-j+2…si-1 = p1p2…pj-1,見黃色的部分)。所以有:

1、 si-k+1si-k+2…si-1 = pj-k+1pj-k+2…pj-1。

所以當p前移到k時,有:

2、 si-k+1si-k+2…si-1 = p1p2…pk-1。

通過1,2有

pj-k+1pj-k+2…pj-1 = p1p2…pk-1。

呵呵,此時我們的任務就是求這個k值了。。。

理解了這一點之後,終於能夠發現此演算法的經典了。

記錄KMP演算法,記錄其經典之處。。。

離開學校已經多年了,早已經不再撫弄那些陳舊的書籍。週末,深圳的天氣陰沉,老天這段時間總是很樂意顯擺,動不動就給深圳人民來次幾十年一遇的暴雨,似乎要把一年的雨水全部在這些天下完似的。所以呆在家裡面看電視,上網,實在也無聊。隨手翻開大學時候的 資料結構,還留著啊,當初剛出來的時候總沒有底氣,總希望能夠隨...

KMP演算法(2) 其細微之處

系列文章目錄 kmp 演算法 1 如何理解 kmp kmp演算法 2 其細微之處 本篇來談一談kmp的一些細微之處,直接進入主題。p為模式串,下標從0開始 void getnext string p,int next else j next j 在s中找到p第一次出現的位置 int kmp stri...

KMP演算法記錄

kmp演算法這篇寫的很好,非常好理解 這個演算法用來做字串匹配。字串匹配是計算機的基本任務之一。如果給出兩個字串text 和 pattern 需要判斷字串pattern 是否為字串text 的子串。一般把字串text 稱為文字串,而把字串pattern 稱為模式串。舉例來說,有乙個字串 bbc ab...