擴充套件kmp演算法講解

2021-07-10 02:31:06 字數 1988 閱讀 2300

參考文章

一.擴充套件kmp得到的是什麼

字串a,b。b是模式串(子串)。求解a[i ……lena -1]與b的最長公共字首,記錄在陣列ex[i]中

二.演算法實現

分為兩步,第一步是對b模式串進行處理也是求b[i,blen - 1]與b的最長公共字首,用next陣列儲存,第二部是將a與b進行匹配,其實他們的方法是一樣的

我們先對第二步進行分析

首先假設b的nexta的值已經全部求出,且i之前全部的ex值也已經求出,再設p為匹配過程中的最大位置,設k為達到最大位置時的起始位置,由此可知p = k + ex[k] - 1

由ex的定義可知:a[k……k + ex[k] -1]   與b[0……ex[k] - 1]相等 顯然i > k  所以 a[i……k + ex[k] - 1]  

與 b[i - k……ex[k]-1] 匹配,設l = nexta[i - k],根據nexta的定義有b[0……l-1]  = b[i-k……i - k + l - 1]

只需判斷ex[k] - 1(=p - k ) 與 i - k + l - 1那個大

1.i - k + l - 1 < p - k    及 p > i + l - 1,p >= i + l

由a[i……p]  與 b[i - k……p-k] 匹配得到a[i……l + i - 1]

與b[i - k……i - k + l - 1] ,又有b[0……l-1]  = b[i-k……i - k + l - 1]。故a[i……l + i - 1]

= b[0……l-1] 

可知ex[i] >= l,如果ex[i] > l則a[i……l + i ]

= b[0……l] .因為p = k + ex[k] - 1

>= i + l,所以a[i……l + i] = b[i - k……i - k + l],推出b[0……l] = k + ex[k] - 1與next陣列定義不符合。所以ex[i] = l

2.i - k + l - 1 >= p - k    及 p <= i + l - 1,p < i + l

a[i……p]  = b[i - k……p-k]

b[0……l-1]  = b[i-k……i - k + l - 1] 所以b[0……p -i]  = b[i-k……p - k]

所以a[i……p]  = b[0……p -i],p是匹配到的最遠的地方,需要繼續從a[p + 1] 和 b[p - i + 1]開始繼續匹配

設j = p - i + 1

,則 p  + 1 = i + j。p增加了,所以要更新p和k的值

ps:注意j如果是小於零的就讓j = 0,從b的最前端開始匹配

第一步顯然和第二步的方法是一樣的,注意第一步中都是nexta陣列

對於b來說nexta[0]  肯定等於n,然後求出nexta[1]的最遠距離,另k = 1,不用對p賦值

對於ab匹配來說,要遍歷求出extend[0],遍歷應該到兩個字串中長度較短的乙個就停止。並另k = 0。

**如下

//需定義extend 和 nexta

void

ekmp

(char s,

char t)

//s主串,t模式串

nexta[1]

= k;

k =1;

int p,l,j;

for(

int i =

2; i < tlen; i ++)

else

nexta[i]

= j;

k = i;}}

for(k =

0;k < len && s[k]

== t[k];k ++

) extend[0]

= k;

k =0;

for(

int i =

1; i < slen; i ++)

else

extend[i]

= j;

k = i;}}

}

kmp演算法講解

kmp演算法本身,解決的是判斷模板字串t,是否是字串s的子串的問題。當只需判斷子串首次出現的位置,或是否包含子串。可以用庫函式strstr s,t 代替,判斷t是否為s的子串來代替。該函式的返回值是t首次出現的位置,如果t不是s的子串則返回null。該函式的複雜度與kmp類似。kmp演算法主要分為兩...

KMP演算法講解

第一次寫部落格有點小激動,今天要講一下kmp演算法,這個查詢演算法比較難理解,我也是想了很久才想明白,我們在str2中的pos位置開始查詢str1,當找到的時候返回str2中的下標,沒有找到的時候返回 1 首先我們來參考一下我們最初寫的查詢字串的函式,定義i 0為str2的下標,j 0為str1的下...

擴充套件KMP 講解 模版 例題

在閱讀這篇文章之前,我們假定你已經掌握了kmp n 1次探裡的定義。擴充套件kmp解決的是源串s的每乙個字尾與模式串p的最長公共字首的長度的問題,並求解出答案extend陣列,例如,ababac與aba的extend陣列是3 0 3 0 1 0,這裡extend i 表示s i 5 i從0開始 與p...