KMP演算法 NEXT陣列

2021-07-23 13:52:34 字數 1633 閱讀 8825

kmp和next陣列基本上是一起用的,有了next陣列,才有kmp演算法,講道理來說這兩個都是基於最大前字尾和,也就是說需要用到kmp的時候必須先把next陣列先求出來,next陣列就是由所匹配的word的每個子串的前字尾和最大匹配得到的,說實話next陣列的演算法給優化得已經很無解了,以至於至今我也只能理解一半。。

next陣列是由最大前字尾匹配和求得的,這個最大前字尾匹配和是什麼東西呢,下面舉個栗子。

比如說你要匹配的word叫abcabk

對於從0-i的子串(i是當前陣列下標),

當i等於0時,子串為a,字首和字尾都為空,所以最大匹配為0

當i等於1時,子串為ab,字首和字尾分別為a和b,最大匹配為0

當i等於2時,子串為abc,字首為a,ab,字尾為c,bc,最大匹配為0

當i等於3時,子串為abca,字首為a,ab,abc字尾為a,ca,bca,最大匹配為1

當i等於4時,子串為abcab,字首為a,ab,abc,abca,字尾為b,ab,cab,bcab,最大匹配為2

當i等於5時,子串為abcabk,字首為a,ab,abc,abca,abcab,字尾為k,bk,abk,cabk,bcabk,最大匹配為0

所以next陣列就出來了,為:

0 0 0 1 2 0

但是這只是串比較小,對稱度比較小的時候,如果要用程式實現又要怎麼辦呢。把所有子串都求出來?如果按照最暴力的寫法,時間複雜度可能為o(n^3),雖然說word通常比較短,但是我們完全沒有必要花辣麼多時間在匹配next陣列上。

這種中間過程需要優化的,不用說,都想到了動態規劃,壓縮中間過程。

那我們再看看規律:

1、 當前面字元的前乙個字元的對稱程度為0的時候,只要將當前字元與子串第乙個字元進行比較。這個很好理解啊,前面都是0,說明都不對稱了,如果多加了乙個字元,要對稱的話最多是當前的和第乙個對稱。比如abcabk這個裡面k的是0,那麼後面的a的對稱程度只需要看它是不是等於第乙個字元a了。

#include 

#include

#include

#include

#include

#include

#include

#include

#include

#define maxn 1000000+5

#define minn 100

using

namespace

std;

int *getnext(char *word)

return next;

}int kmp(char *text,char *word)

else

j = next[j];

if(j == l2) //匹配完全,計數器增加

sum++;

} return sum;

} int main()}/*

5hahahaha

wqnwqn

adaadadada

bababb

bababababababababb

dadaddaadaaddaaadaad

*/

KMP演算法 next陣列

通過上文完全可以對kmp演算法的原理有個清晰的了解,那麼下一步就是程式設計實現了,其中最重要的就是如何根據待匹配的模版字串求出對應每一位的最大相同前字尾的長度。我先給出我的 1 void makenext const char p,int next 214 next q k 15 16 現在我著重講...

kmp演算法next例題 KMP演算法next陣列求解

kmp演算法與bf演算法的比較 bf演算法的想法十分樸素,即先將子串t的第一位與主串s的第一位對齊開始匹配,當不能匹配時將子串整體往後移一位,然後重新匹配,以此類推直至排出結果 如當遇到下圖所示情況時,需將子串整體後移一位,將i,j分別回溯到主串第2位和子串第一位。kmp演算法 對bf進行思考後,我...

KMP演算法的next陣列

本文參考 google 資料結構 c語言 include include author silence time 2012 5 19 description kmp演算法的next using namespace std void next char t,int l,int next else 1 ...