字串匹配KMP演算法學習筆記

2021-10-23 15:47:18 字數 1185 閱讀 8969

字串匹配,leetcode28題。時間複雜度o(mn)的演算法大家都會,題解裡面官方賬號給出的利用字串雜湊判等的o(n)演算法也很優秀。本篇的重點是kmp演算法。

如果還不是很好理解,可以看labuladong的題解。乙個kmp演算法易理解版本,講解的部分也很清楚。

本篇主要是對此題解做乙個補充,個人感覺題解中對「影子狀態」,x的表述不是很清楚,原題解說的是所謂影子狀態,就是和當前狀態具有相同的字首

其實此題解裡面的x,就是原kmp演算法裡,字串具有相同字首字尾的子字串的字首下標(好像有點繞)。就借用題解裡面的例子吧,例如下圖。為什麼j = 4的時候,x = 3呢?其實就是因為在abab這個字串中,長度為2的字首和長度為2的字尾是相同的(都是ab)。

同理,為什麼j = 3的時候,x = 1呢?就是因為字串aba中,長度為1的字首和長度為1的字尾是相同的,這就吻合了kmp演算法。

題解中,個人感覺比較難想到的難理解的是對「影子索引」更新的那一句**,即x = dp[x][needle[idx]];其實帶入我們上面對x意義的說明,就很清楚了,這句**其實就是與當前字串字尾相同的字首長度是x,遇到字元 pat[j],那麼如果字尾加上pat[j],與字尾相同的字首長度是多少?換言之,該定位到 **去?(比如是0的話,那麼就沒有這樣的字首)。

對x的解釋我們都清楚了。再說一點我個人對kmp演算法的思考,之所以它相比於暴力解法能獲得加速,就在於假如當前匹配到的位置沒有與字尾相同的字首的話,我們就不必再在這裡匹配的,不可能匹配的。比如這個例子

kmp演算法會不會漏解呢?只需要跑一下例子pattern = 「aaaaf」,target = "******aaaaaf",看一下對於pattern中每個位置,x的值是多少就可以理解,不會有漏掉的解。

完整**:

int strstr(string haystack, string needle) 

//開始匹配了

int j = 0;

for(int idx = 0;idx < len_1;idx++)

return -1;

}

學習筆記 KMP 字串匹配

目錄完整 最初學這個演算法,是在新初一的暑假裡,乙個初三即將畢業的學長給我們講的。當時聽得不是很懂,模板題也就只有 28pts。後來過了好久,又想起來重新學一遍字串,從 kmp 到 sam 都來一遍。於是便有了這片文章。kmp 演算法是由三名姓氏首字母分別為 k m p 的牛人發明的演算法。雖然我不...

KMP演算法 字串匹配

kmp演算法基本思想 我們在用常規的思想做 字串匹配時候是 如 對如 字元如果 t abab 用p ba 去匹配,常規思路是 看 t 第乙個元素 a 是否 和p 的乙個 b 匹配 匹配的話 檢視各自的第二個元素,不匹配 則將 t 串的 第二個元素開始 和 p 的第乙個匹配,如此 一步一步 的後移 來...

KMP字串匹配演算法

kmp核心思想 計算模式串的next陣列,主串的索引在比較的過程中不回朔 ifndef kmp h define kmp h class kmp endif include kmp.h include include include using namespace std int kmp calcu...