從頭到尾徹底理解kmp演算法,這是我在搜尋各種部落格之後,解釋的最為詳盡的一篇關於介紹kmp演算法的一篇部落格。自己的理解也算是建立在這篇部落格上。很早很早之前就已經學過了,不過還是忘了好多。現在再拾起來按照自己的理解疏解一遍。
目標問題,給你乙個文字串s,文字串t求出s中與t相匹配的第乙個位置。
我們有樸素的演算法是:
int j=1;
int i=1;
int s0=strlen(s);
int tp=strlen(t);
while(i<=s0&&j<=t0)
else
}
這是最為簡單的暴力演算法,同時我們也會發現,每一次匹配不成功的時候我們都會要去從頭開始匹配。ab
cdea
bbde
如上圖所示當abc與abb失配的時候我們會將a再與b去匹配,但是實際上我們早已經知道了第二個字元是b。所以如此顯而效率會較為低下.
knuth-morris-pratt 字串查詢演算法,簡稱為 「kmp演算法」,常用於在乙個文字串s內查詢乙個模式串p 的出現位置,這個演算法由donald knuth、vaughan pratt、james h. morris三人於2023年聯合發表,故取這3人的姓氏命名此演算法。
簡要思路:當我們匹配到s字串中的第i個位置的時候,此時匹配到t字串的第j個字元,此時有i-j+1位置到i位置與t字串中的字元相匹配。
如果第j+1個字元相匹配,接著向下進行匹配即可。我們先來看kmp演算法的**如果第j+1個字元失配,我們就控制s中字元位置不發生改變,將t向後滑動一段位置。(next[j])
int j=0;
int s0=strlen(s);
int t0=strlrn(t);
while(it0)
return i-t0;
else
return 0;
}
**中next即為向右滑動的值。那麼如何去理解這個next值則成了關鍵,自己也被折磨了好久好久。
int j=0;
int i=1;
next[1]=0;
int t0=strlen(t);
while(i理解如下ab
cdab
cabc
dabd
abcd
abd0
1111
12在這裡j所表示的含義代表著第j個字元位置前面與t字串從頭開始最大匹配長度。拿上面**舉例來說,在最後乙個位置我們發生了失配問題,d之前與字串t從頭匹配最大長度為2,截至到c為止。所以我們就將字串的位置滑到了c處。next的值所表示的東西就是j處字元前面的字元與t字串從頭開始匹配的最大長度!!!
但其實截至到現在這個演算法還不算完美,因為我們還會有一種極特殊的情況。aa
aaab
0123
45比如上面**所列處的這種結構當b失配的時候我們右移到了左邊的a的位置,a失配後我們右移到了第四個a的位置,但顯然我們之前已經知道了肯定會失配的結果。ab
adea
babe
0112
1b失配移到了第二個位置但這個時候還是b,所以所得結果依然會是失配,明知故作?
實際上是我們求next的過程中有點小疏漏,這個時候應該要能夠滿足如果j==t[next[j]]那麼j=next[next[j]],因為如果t[j]=t[next[j]]則肯定失配,則應該盡量避免這種狀況。
int j=0;
int i=1;
int t0=strlen(t);
while(i<=t0))
} else
}
自己目前也理解的不是特別充分,也只能將自己想出來的,大概寫出來成這個樣子了,實在理解不了的話可以採取強制記憶措施,只不過實在不是太好的樣子。
up!up!
KMP演算法最淺顯理解 一看就明白
kmp演算法看懂了覺得特別簡單,思路很簡單,看不懂之前,查各種資料,看的稀里糊塗,即使網上最簡單的解釋,依然看的稀里糊塗。我花了半天時間,爭取用最短的篇幅大致搞明白這玩意到底是啥。這裡不扯概念,只講演算法過程和 理解 字串匹配。給你兩個字串,尋找其中乙個字串是否包含另乙個字串,如果包含,返回包含的起...
KMP演算法最淺顯理解 一看就明白
目錄 說明 kmp演算法求解什麼型別問題 演算法說明 解析 kmp測試 複雜度分析 進一步說明2018 3 14 kmp演算法看懂了覺得特別簡單,思路很簡單,看不懂之前,查各種資料,看的稀里糊塗,即使網上最簡單的解釋,依然看的稀里糊塗。我花了半天時間,爭取用最短的篇幅大致搞明白這玩意到底是啥。這裡不...
KMP演算法(淺顯易懂)
kmp演算法求解什麼型別問題 字串匹配。給你兩個字串,尋找其中乙個字串是否包含另乙個字串,如果包含,返回包含的起始位置。講道理 大串a 長度n 小串b 長度m 一般匹配字串,乙個乙個比,當前字元對了則比對下乙個,不對了再從b的頭開始比,移動乙個位置 這樣的時間複雜度是o n m kmp可以實現複雜度...