字串匹配演算法 KMP詳解

2021-07-09 16:04:45 字數 1147 閱讀 3230

這兩天在看字串匹配演算法,第一次看到kmp演算法的時候覺得很難。於是上網搜分析,網上講kmp的演算法很多,只是好像很多都講的雲裡霧裡的,不甚清晰。後來想想還是找教材看看,第一回看的是《演算法》第四版,其實沒看懂;於是再找來clrs看,恍然大悟,果然還是clrs**好。本文主要是梳理一下整個思路,盡自己所能講得盡量清晰易懂。

首先先從什麼是字串匹配開始:字串匹配就是給定乙個字串s,然後在另乙個字串t中找出s。具體應用上可以是找出s在t中出現了多少次,s在t中出現的位置等等,也就是很多文字編輯器的ctrl+f的功能了。

顯然這裡存在乙個大家都想得到的原始暴力型的演算法,基本思想就是:把t中的每個字母t[1......m-p]和s[1]中的第乙個字母比較,假設當前比較到t中的第j個字母,且t[j]==s[1],則繼續依次比較t[j+i]和s[1+i],i=1....p-1.其中p為s的長度。直到i==p-1或者t[j+i]!=s[1+i],則終止當前以j為起點的比較,並令j=j+1繼續下一輪的比較;如果一開始t[j]!=s[1]則直接j=j+1,進入下一輪比較。**很簡單,如下:

int search(string s,string t)

return -1;

}

很簡單的一段**。所以現在問題的關鍵在於找到實現get_arr函式,亦即找到s對應的陣列。其實這本身也是kmp演算法的關鍵。

其實這個問題也不難,可以用歸納法來思考。

首先假設當前已經找到a[1...k],則怎麼找a[k+1]呢?根據定義,假設 a[k] = q,則s[1.....q] = s[p....k],其中k-p=q-1;所以a[k+1]最大應該等於q+1,但如果s[k+1]!=s[q+1],則a[k+1]

由以上描述可以知道,我們可以遍歷當前的所有 "既是s[p....k]的字尾表示式,又是s的字首表示式" 的子串,假設為s[1.....f],然後找出滿足s[f+1]=s[q+1]的最大f,此時可得到 a[k+1]=f。

根據以上描述**如下:

void get_arr(string s,vector&a)

}

字串KMP匹配演算法詳解

下面我再來舉個具體例子,並給出一具體執行程式 對於目的字串big是banananobano,要匹配的字串small是nano,的情況,下面是匹配過程,原理很簡單,只要先和big字串的第乙個字元比較,如果相同就比較下乙個字元 他們的第二個字元 如果不同就把small整體右移乙個,之後再從small的第...

字串匹配KMP演算法詳解。

一 什麼是kmp演算法 假設現在有這樣乙個問題 有乙個文字串s,和乙個模式串p,現在要判斷s中是否有和p匹配的子串,並查詢p在s中的位置,怎麼解決呢?如果用暴力匹配的思路,並假設現在文字串s匹配到 i 位置,模式串p匹配到 j 位置,則有 如果當前字元匹配成功 即s i p j 則i j 繼續匹配下...

KMP字串匹配演算法詳解

kmp演算法利用匹配失敗後的資訊,儘量減少模式串與主串的匹配次數以達到快速匹配的目的。具體實現就是實現乙個next 函式,函式本身包含了模式串的區域性匹配資訊。時間複雜度o m n 例如 第 j 1 個字元的next函式值next j 1 等於3,意味著它的前三個字串,s j 2 s j 1 s j...