KMP字串模式匹配演算法

2021-10-08 17:44:36 字數 1713 閱讀 4796

1 演算法思想:分別用計數指標i和j指示主串s和模式串t中當前正待比較的字串位置。從主串s的第乙個字元起,與模式串t的第乙個字元比較,若相等,則繼續逐個比較後續字元;否則從主串的下乙個字元起,重新和模式的字元比較;以此類推,直至模式t中的每乙個字元依次和主串s中的乙個連續的字串行相等,則稱匹配成功,函式值為與模式t中第乙個字元相等的字元在主串s中的序號,否則匹配不成功,函式值為0。

2 實現**:

s="ababcabcac",t="abcac",結果應該為6。

//簡單字串匹配演算法(時間複雜度o(mn))

#include #include using namespace std;

int index(string s, string t)else

} if(j>t.length())

return i-t.length();

else return 0;

}int main()

執行結果:

kmp 演算法是 d.e.knuth、j,h,morris 和 v.r.pratt 三位神人共同提出的,稱之為 knuth-morria-pratt 演算法,簡稱 kmp 演算法。該演算法相對於 brute-force(暴力)演算法有比較大的改進,主要是消除了主串指標的回溯,從而使演算法效率有了某種程度的提高。

上面說道 kmp 演算法主要是通過消除主串指標的回溯來提高匹配的效率的,那麼,它是則呢樣來消除回溯的呢?就是因為它提取並運用了加速匹配的資訊!

這種資訊就是對於每模式串 t 的每個元素 t j,都存在乙個實數 k ,使得模式串 t 開頭的 k 個字元(t 0 t 1…t k-1)依次與 t j 前面的 k(t j-k t j-k+1…t j-1,這裡第乙個字元 t j-k 最多從 t 1 開始,所以 k < j)個字元相同。如果這樣的 k 有多個,則取最大的乙個。模式串 t 中每個位置 j 的字元都有這種資訊,採用 next 陣列表示,即 next[ j ]=max。

加速資訊,即陣列 next 的提取是整個 kmp 演算法中最核心的部分,弄懂了 next 的求解方法,也就弄懂了 kmp 演算法的十之七八了,但是不巧的是這部分**恰恰是最不容易弄懂的……

先上**:

void getnext(int next,string t)

先來看一下上面演算法存在的缺陷:

顯然,當我們上邊的演算法得到的next陣列應該是[ -1,0,0,1 ]

所以下一步我們應該是把j移動到第1個元素咯:

不難發現,這一步是完全沒有意義的。因為後面的b已經不匹配了,那前面的b也一定是不匹配的,同樣的情況其實還發生在第2個元素a上。

顯然,發生問題的原因在於t[j] == t[next[j]]。

所以我們需要新增乙個判斷:

void getnext(int next,string t)

{ int j=0,k=-1;

next[0]=-1;

while(j

字串模式匹配KMP演算法

next的值去改變每次匹配的位置 注意 字串的儲存最好用字元陣列,然後用字元輸入的形式,保證正確!利用求模式串的next值來分析遍歷,可以在不改變主串i的值的基礎上,只改變next j 的下標來遍歷 next j include include using namespace std void ge...

字串模式匹配KMP演算法

字串模式匹配指的是,找出特定的模式串在乙個較長的字串中出現的位置。很直觀的可以寫出下面的 來找出模式串在乙個長字串中出現的位置。1 2 樸素的模式匹配演算法 3 功能 字串的模式匹配 4 引數 5 s 目標串 6 p 模式串 7 pos 開發匹配的位置 8 返回值 9 匹配成功,返回模式串在目標串的...

字串模式匹配KMP演算法

字串模式匹配指的是,找出特定的模式串在乙個較長的字串中出現的位置。很直觀的可以寫出下面的 來找出模式串在乙個長字串中出現的位置。1 2 樸素的模式匹配演算法 3 功能 字串的模式匹配 4 引數 5 s 目標串 6 p 模式串 7 pos 開發匹配的位置 8 返回值 9 匹配成功,返回模式串在目標串的...