詳解又詳解KMP中的next和nextval的演算法

2021-08-17 11:08:15 字數 1532 閱讀 7191

kmp演算法是一種改進的字串匹配演算法,由d.e.knuth,j.h.morris和v.r.pratt同時發現,因此人們稱它為克努特——莫里斯——普拉特操作(簡稱kmp演算法)。

以下借用的部分內容 

這種演算法不太容易理解,網上有很多解釋,但讀起來都很費勁。直到讀到這篇文章,我才真正理解這種演算法。下面,我用自己的語言,試圖寫一篇比較好懂的kmp演算法解釋。

首先,字串」bbc abcdab abcdabcdabde」的第乙個字元與搜尋詞」abcdabd」的第乙個字元,進行比較。因為b與a不匹配,所以搜尋詞後移一位。

因為b與a不匹配,搜尋詞再往後移。

就這樣,直到字串有乙個字元,與搜尋詞的第乙個字元相同為止。

接著比較字串和搜尋詞的下乙個字元,還是相同。

逐位比較,直到發現c與d不匹配。於是,繼續將搜尋詞向後移動。

逐位比較,直到搜尋詞的最後一位,發現完全匹配,於是搜尋完成。

標號(j)12

3456

7模式串(p)ab

cdab

d——就是回溯到存在」對稱「的地方。

從第2部分圖中可以分析得出,當掃瞄到模式串中某一位發現不匹配,總是回溯到在這一位之前的部分模式串存在重複的地方

所以,next(j)就是當模式串第j位不匹配時即將要退回到的字母標號

不管第一位和第二位是什麼,第一位next(1)=0,第二位next(2)=1,這是固定的。

當j=3時,p(j)=c,c之前有」ab」,不存在重複(0位),所以next(3)=0+1=1; 

當j=4時,p(j)=d,c之前有」abc」,不存在重複(0位),所以next(4)=0+1=1; 

當j=5時,p(j)=a,c之前有」abcd」,不存在重複(0位),所以next(5)=0+1=1; 

當j=6時,p(j)=b,c之前有」abcda」,存在重複」a」(1位),所以next(6)=1+1=2; 

當j=7時,p(j)=d,c之前有」abcdab」,存在重複」ab」(2位),所以next(7)=2+1=3;

觀察第5位」a」,當它不匹配時,按照next行回溯到標號1也為字母a,這時再匹配a是徒勞的,因為已知a不匹配,所以就繼續退回到標號1字母a的next(1)=0。為了直接點進行優化,就有了nextval行:

j=5,p(5)=a,next(5)=1,p(1)=a=p(5),所以nextval(5)=next(1)=0; 

j=6,p(6)=b,next(6)=2,p(2)=b=p(6),所以nextval(6)=next(2)=1; 

j=7,p(7)=d,next(7)=3,p(3)=c!=p(7),所以nextval(7)=next(7)=3;

標號(j)12

3456

7模式串(p)ab

cdab

dnext01

1112

3nextval01

1101

3詳解完畢,希望大家喜歡。

原文 

KMP演算法的next函式詳解

不得不說,kmp的next函式是在是難以理解,智商拙計。在幾天的斷斷續續理解之後一度想放棄,在得知了它的別名看毛片後重新提起了興趣。kmp演算法理解的難點在於next遞推的理解,也就是說當next j k的時候,如何求出next j 1 的值。先解釋一下next j k的意義。這說明在子串中該j位置...

next 和nextLine的詳解

關於next 和nextline 方法的簡述 返回迭代的下乙個元素。next 返回輸入的字元 1 一定要讀取到有效字元後才可以結束輸入。2 對輸入有效字元之前遇到的空白,next 方法會自動將其去掉。3 只有輸入有效字元後才將其後面輸入的空白作為分隔符或者結束符。4 next 不能得到帶有空格的字串...

kmp中next和nextval的區別

模式匹配。kmp中next陣列表示如果當前匹配不成功,匹配串移動到的位置,不考慮移動到的位置的數與當前位置數的關係。kmp中nextval陣列表示如果當前匹配不成功,匹配串移動到的位置,考慮移動到的位置的數與當前位置數的關係。求next cpp view plain copy while i els...