字串查詢演算法kmp

2021-06-27 15:58:06 字數 1297 閱讀 6460

字串查詢最簡單的方法就是乙個乙個地「滑動」查詢。這樣查詢演算法複雜度可定很高,假設pattern的長度為m,文字txt的長度為n,那麼演算法複雜度為o(m(n-m-1))。

kmp模式搜尋演算法

kmp(knuth morris pratt)我只認識knuth,大名鼎鼎的高納德老頭子嘛。

kmp演算法的基本思想是,當「失配」的時候,利用之前已經比較過的字串資訊,確定重新開始比較時pattern串的開始的位置,而不是每次都要從頭開始比較。

kmp演算法先預處理一下pattern串pat,構造出來乙個lps陣列,lps的意思是longest proper prefix which is also suffix(最長字首也是最長字尾)。對於字串pat[0...i],i取值可以是0到m,m是pat的長度。lps[i]儲存的值是子模式串pat[0...i]的最大字首字尾的長度。

lps[i] = the longest proper prefix of pat[0..i] 

which is also a suffix of pat[0..i].

examples:

for the pattern 「aabaacaabaa」, lps is [0, 1, 0, 1, 2, 0, 1, 2, 3, 4, 5]

for the pattern 「abcde」, lps is [0, 0, 0, 0, 0]

for the pattern 「aaaaa」, lps is [0, 1, 2, 3, 4]

for the pattern 「aaabaaa」, lps is [0, 1, 2, 0, 1, 2, 3]

for the pattern 「aaacaaaaac」, lps is [0, 1, 2, 0, 1, 2, 3, 3, 3, 4]

搜尋演算法:

不像簡單搜尋方法那樣乙個字元乙個字元的滑動搜尋,我們用lps確定pattern串滑動的位置。下面詳細說明具體怎麼比較:當pat[i]和txt[i]失配的時候,pat[0...j-1]和txt[i-j+1...i-1]是匹配的。如果滑動一位去再次比較,那麼這pat[0...j-1]個字元肯定不匹配了。那麼應該滑動多少位呢?這是就用到lps了,這是滑動lps[j-1]位.

預處理演算法:

#include #include #include // ***** search

void search(char* txt,char* pat)

{ int n=strlen(txt);

int m=strlen(pat);

for(int i=0;i

字串查詢演算法kmp

給定乙個文字串s,和乙個匹配串p,要求查詢p第一次在s中出現的位置。常見的方法如暴力搜素,逐個匹配s i p j 若匹配,下標後移。不匹配,i回溯到這次匹配前的下一位置,j置為0,重新匹配。最壞情況,時間複雜度o n m int violencesearch char s,char p else i...

字串查詢KMP演算法

如果你用過ctrl f這個快捷鍵,那麼你有很大的概率使用過這個演算法,這就是在待查詢字串 可能有成千上萬個字元 中找出模式串 比較小,可能有幾個字元 可能找到大於或者等於1次的位置。例如,在ababcd中找出abc。這裡介紹演算法思想,只給出了第一次出現的位置。void find char t,ch...

KMP 演算法 字串查詢演算法

knuth morris pratt algorithm 克努斯 莫里斯 普拉特 演算法 克努斯 莫里斯 普拉特演算法 部分匹配表 字首 指除了最後乙個字元以外,乙個字串的全部頭部組合 字尾 指除了第乙個字元以外,乙個字串的全部尾部組合 部分匹配值 就是 字首 和 字尾 的最長的共有元素的長度。以 ...