參考文章
一.擴充套件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...