演算法 KMP演算法學習筆記

2021-09-11 07:52:09 字數 1769 閱讀 3832

kmp演算法是一種改進的字串匹配演算法,由d.e.knuth,j.h.morris和v.r.pratt同時發現,因此人們稱它為knuth——morris——pratt操作(簡稱kmp演算法)。kmp演算法的關鍵是利用匹配失敗後的資訊,儘量減少模式串p(長度為m)與主串t(長度為n)的匹配次數以達到快速匹配的目的。具體實現就是實現乙個next()函式,函式本身包含了模式串的區域性匹配資訊。時間複雜度為o(m+n)。

以下為我理解內容:

相對暴力的解決方法,kmp在t的[ i-j, i-1 ]與p的[0, j -1]匹配且t[i]!=p[j]時,索引j下一步指向的位置標記為next(j).

即在kmp演算法中,要求next函式滿足:t的[ i-next(j), i-1 ]   與  p的[0, next(j) - 1] 是匹配的 。

又因為t的[ i-j, i-1 ]與p的[0, j -1]匹配,所以next函式應該滿足p的[0, next(j) - 1] 與 p的[j - next(j), j -1]是匹配的。即:

next(j)的含義應該是在p字串的[ 0, j - 1]中滿足字首字串和字尾字串匹配的最大字串長度。

public static int next(string p) 

return next;

}

next函式的實現:

由於next(j)為p字串的[ 0, j - 1]子字串中滿足字首字串和字尾字串匹配的最大字串長度。所以

當j==0時,子字串[ 0, j - 1]不存在,設定next(0) = -1。

當j==1時,子字串[ 0, j - 1]是[0, 0],由於字串本身是其自己的字首和字尾,所以設定next(1) = 0;

當j > 1且p[j] == p[k]時,由於子字串[ 0, k - 1] ( = [ j - k, j - 1] )為子字串[ 0, j - 1]的最長前字尾匹配字串,即next(j) = k.所以next( j + 1 ) = k + 1,即子字串[ 0, j ]的最長前字尾匹配字串長度為k+1;然後繼續去比較p[j + 1] 和 p[k+ 1]是否相等。

當j > 1時且p[j] != p[k]時,此時需要尋找子字串[ 0, j ]的最長前字尾匹配字串。顯然,next(j + 1)肯定小於next(j) = k。所以可以轉變思路為尋找匹配的字串[ 0, k - 1 - x]和[ j - k + x + 1, j]。

又由於next(j) = k

所以[ j - k , j - 1] = [0, k - 1 ],即[ j - k + x + 1 , j - 1] = [  x + 1, k - 1  ]

即問題可轉換思路為尋找字串p[0, k]+p[j]的最長前字尾匹配字串。由如下解釋可知,此時next( j + 1 )可通過跳轉至步驟3順序執行進行求解:

當p[j] == p[k]時,字串[ 0, j ]的最長前字尾匹配字串長度next( j + 1 ) = next (k ) + 1

當p[j] != p[k]時,字串[ 0, j ]的最長前字尾匹配字串長度next( j + 1 )求解跳轉至第4步繼續求解。

vectorkmpnext(string p)

return next;

}int strstr(string haystack, string needle)

if(j == n )

return i- j;

if ( i < m &&haystack[i] != needle[j])

}return -1;

}

Kmp演算法學習筆記

kmp演算法我認為難點在next陣列的建立。看kmp前我仔細看了下傳統的匹配模式,為 首元素存放串的長度 int index sstring s,sstring t else i i j 2 if j t 0 return i t 0 else return 0 我認為想深刻理解好kmp演算法要和傳...

KMP演算法學習筆記

kmp是一種字串匹配演算法,網上有許多的講解和介紹,都非常清楚明白,這裡只說明一點next i 表示 1,i 1 位中的最長公共字首字尾,因此在遇到字元不匹配時,直接將字串右移j next j 位即可。不多說了,直接上習題 poj 3461 oulipo kmp演算法裸題,直接上模板 code in...

KMP演算法學習筆記

前幾天學習了關於字串處理的kmp演算法,剛學的時候沒怎麼懂,通過今天的練題,終於把kmp掌握了。kmp演算法利用了字串的一些特殊性質,通過字首陣列,將單個字串的匹配問題由o m n 優化到了o m n 這裡,我存幾段關鍵性 首先是get next 函式 void get next 然後是kmp vo...