系列文章目錄本篇來談一談kmp的一些細微之處,直接進入主題。kmp 演算法(1):如何理解 kmp
kmp演算法(2):其細微之處
上述**的起始下標都是從0開始的,但每個人對陣列起始位置的編碼習慣不同,大致分為兩類:0和1。對於上面的**,起始位置如果改為1的話又是怎樣呢?/* p為模式串,下標從0開始 */
void getnext(string p, int next)
else
j = next[j];
}}/* 在s中找到p第一次出現的位置 */
int kmp(string s, string p, int next)
else
j = next[j]; //當前字元匹配失敗,進行跳轉
}if (j == p_len) //匹配成功
return i - j;
return -1;
}
它們的區別之處很容易看出來,整體的**結構不變。但它們的區別並不止如此。我們知道,kmp演算法的next[i]表示相同的最長前字尾,但這對起始位置為1的next[i]卻不再適用。i0
1234
567模式串ab
cdab
d『\0』
next[ i ]-10
0001
20 i
1234
5678
模式串abc
dabd
『\0』
next[ i ]01
1112
31上面兩幅圖表展示的是:相同模式串下不同起始位置的next值對比。
相比之下,起始位置為1的next值比起始位置為0的next值多了1。多1,不是巧合,而是必然。這很容易證明。
在getnext()中,j從0開始(起始位置為1),在走了相等步後停下依次賦值給next[i],因此相較於起始位置為0的next總是多1。這又引起了我們的思考,多了1後在模式匹配中,next還會正確的實現跳轉麼?當然會了,next多1,同時模式串的起始位置也多了1,這就好比數學中,從a=b轉化為a+1=b+1,形式不同但完全等價。
先來看乙個問題,在主串s中找到模式串p所有可以完全匹配的位置。
很簡單,典型的kmp模式匹配。
假設起始位置都是從0開始,對於上圖,若已找到主串的第乙個完全匹配位置即0–4,那麼請問接下來模式串如何移動?
不知道各位讀者有沒有注意過模式串最後末尾處的next值代表什麼?(末尾即為字串的結尾標誌:』\0』)
它代表整個模式串的最長相同前字尾。
利用這個next值,我們直接可以通過next實現跳轉,更快地找到下乙個匹配點。
文章**我的個人部落格:
記錄KMP演算法,記錄其經典之處。。。
離開學校已經多年了,早已經不再撫弄那些陳舊的書籍。週末,深圳的天氣陰沉,老天這段時間總是很樂意顯擺,動不動就給深圳人民來次幾十年一遇的暴雨,似乎要把一年的雨水全部在這些天下完似的。所以呆在家裡面看電視,上網,實在也無聊。隨手翻開大學時候的 資料結構,還留著啊,當初剛出來的時候總沒有底氣,總希望能夠隨...
記錄KMP演算法,記錄其經典之處。。。
離開學校已經多年了,早已經不再撫弄那些陳舊的書籍。週末,深圳的天氣陰沉,老天這段時間總是很樂意顯擺,動不動就給深圳人民來次幾十年一遇的暴雨,似乎要把一年的雨水全部在這些天下完似的。所以呆在家裡面看電視,上網,實在也無聊。隨手翻開大學時候的 資料結構,還留著啊,當初剛出來的時候總沒有底氣,總希望能夠隨...
字串查詢 2 KMP演算法
knuth morris pratt字串查詢演算法,簡稱kmp演算法,常用於在乙個文字串s中查詢乙個模式串p出現的位置,因為這個演算法有donald knuth,vaughan pratt,james h.morris與1977年聯合發表,因此取這3個人的姓氏的命名此演算法。int kmpsearc...