看毛片演算法又稱kmp演算法。該演算法之所以得名無外乎如下原因。
每當涉及該演算法都甚新鮮,極想把玩一番,經過一番琢磨,終於悟透其本質。遂將其束之高閣,數月之後,再相邂逅,新鮮如初,又是一番把玩、醒悟、遺忘,如此迴圈以至無窮。足見,該演算法與看毛片的道理一脈相承。初看新鮮刺激,觀摩研究,醒悟不過如此而已。遂撇下而顧其它,數月之後,複習之,依然新鮮激動如故。以致數年。
kmp演算法核心在於求匹配失敗時模式串的後退陣列,大多數都命名為next陣列,感覺pre應該更符合直覺。假設在t[i] 和p[j]處失配,j必須是往回退的不可能在向前走。因此要求的後退陣列應該這個樣子:pre[sizeof(p)]
(1)t[i] 和p[j]處失配,則找到pre[j],假設pre[j]=k,意味著p有相同的字首和字尾,且長度為k,此時在j處失配,自然要回退,退到哪?退到k處。
(2)咋求pre[j+1]呢?要分兩種情況,
a)pre[j]=pre[k], 所以pre[j+1]=k+1=pre[j]+1,中間那個k+1難理解?要知道k是什麼意思,k是p[0..j]的相同字首和字尾長度,此時兩個綴的後面各增加了乙個相同的字元,所以pre[j+1]自然要在k的基礎上+1了;
b)pre[j]!=pre[k],這就意味著pre[j+1]的相同字首和字尾不能用pre[j]那一套了。此時,要有遞迴的思想了,要觀察更早的字首和字尾是否能滿足pre[j]=pre[k],如果找到這個位置則可基於此求出pre[j+1]了。如果一直往前看,一直沒發現滿足要求的字首和字尾,咋整?不咋整,說明p[0..j+1]不存在相同的字首和字尾,此時如果t[i+1]和p[j+1]失配了,p就只能從頭開始了。找不到在**中這樣表示pre[0]=-1。
上面基本就是看毛片演算法的精髓。還是結合**來理解吧。程式不會看會的,得寫!
int kmp(char *t, char *p)
else j = prev[j];
if (j == psize) return i - j;
else return -1;
}
求後退陣列加模式匹配,世界上基本不會有比這更短的kmp了! KMP演算法簡析
首先,kmp演算法是解決字串匹配問題的演算法,即在主串 s 中查詢子串 t。我們從問題入手,要在主串中查詢子串,顯然可以是用蠻力法逐個遍歷,即從主串的第乙個字元開始和子串的第乙個字元比較,若相等則繼續比較後續字元,若果不相等,則從主串的下乙個的字元 子串的第乙個字元重新開始比較。如果在主串遍歷完之後...
KMP演算法小析
對於串的模式匹配演算法,相信學data structure的都不會很陌生,不過當我們看到各種書上對演算法kmp的講解時,我們會有種不知所云的感覺就算有的c 的演算法實現,和例子的講解,當換成另外乙個串時,我們將無從下手,其中對next的求解,更讓我們痛苦。在這裡sinpoal將自己對這個演算法的看法...
Kmp演算法初析
考慮字串匹配問題。假設文字是乙個長度為n nn的字串t tt,模板是乙個長度為m mm的字串p pp,且m n m nm n。尋找匹配點使得t i p 0 t i m 1 1 p m 1 t i p 0 t i m 1 1 p m 1 t i p 0 t i m 1 1 p m 1 樸素方法 列舉起...