擴充套件KMP演算法

2021-06-25 08:57:15 字數 1761 閱讀 8114

擴充套件kmp:

求出a[i..lena-1]與b的最長公共字首長度,記為ex[i](或者說,ex[i]為滿足a[i..i+z-1]==b[0..z-1]的最大的z值)。

擴充套件kmp可以用來解決很多字串問題,如求乙個字串的最長回文子串和最長重複子串。

【演算法】

設next[i]為滿足b[i..i+z-1]==b[0..z-1]的最大的z值(也就是b的自身匹配)。設目前next[0..lenb-1]與ex[0..i-1]均已求出,要用它們來求ex[i]的值。

設p為目前a串中匹配到的最遠位置,k為讓其匹配到最遠位置的值(或者說,k是在0<=i0顯然,p之後的所有位都是未知的,也就是目前還無法知道a[p+1..lena-1]中的任何一位和b的任何一位是否相等。

根據ex的定義可得,a[k..p]==b[0..p-k],因為i>k,所以又有a[i..p]==b[i-k..p-k],設l=next[i-k],則根據next的定義有b[0..l-1]==b[i-k..i-k+l-1]。考慮i-k+l-1與p-k的關係:

(1)i-k+l-1。這時,由a[i..p]==b[i-k..p-k]可以得到a[i..i+l-1]==b[i-k..i-k+l-1],又因為b[0..l-1]==b[i-k..i-k+l-1]所以a[i..i+l-1]==b[0..l-1],這就說明ex[i]>=l。又由於next的定義可得,

a[i+l]必然不等於b[l](否則a[i..i+l]==b[0..l],因為i+l<=p,所以a[i..i+l]==b[i-k..i-k+l],這樣b[0..l]==b[i-k..i-k+l],故next[i-k]的值應為l+1或更大),這樣,

可以直接得到ex[i]=l!

(2)i+k-l+1>=p-k,即i+l>p

。這時,首先可以知道a[i..p]和b[0..p-i]是相等的(因為a[i..p]==b[i-k..p-k],而i+k-l+1>=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]),然

後,對於a[p+1]和b[p-i+1]是否相等,目前是不知道的(因為前面已經說過,p是目前a串中匹配到的最遠位置,在p之後無法知道任何一位的匹配資訊),因此,要從a[p+1]與b[p-i+1]開始往後繼續匹配(設j為目前

b的匹配位置的下標,一開始j=p-i+1,每次比較a[i+j]與b[j]是否相等,直到不相等或者越界為止,此時的j值就是ex[i]的值)。

在這種情況下,p的值必然會得到延伸,因此更新k和p的值。

邊界:ex[0]的值需要預先求出,然後將初始的k設為0,p設為ex[0]-1。

對於求next陣列,也是「自身匹配」,類似kmp的方法處理即可。唯一的不同點也在邊界上:可以直接知道next[0]=lenb,next[1]的值預先求出,然後初始k=1,p=ex[1]

需要嚴重注意的是,在上述的情況(2)中,本該從a[p+1]與b[p-i+1]開始匹配,但是,若p+1

#include #include #define n 500010

int next[n];

int nextval[n];

int extend[n];

char s[n];

char t[n];

void getnext(char *t)

else extend[k]=l;

}}

擴充套件KMP演算法

摘自 問題定義 給定兩個字串s和t 長度分別為n和m 下標從0開始,定義extend i 等於s i s n 1 與t的最長相同字首的長度,求出所有的extend i 舉個例子,看下表 i0 1234 567s aaaa abbb taaa aacextend i 54 3210 00為什麼說這是k...

擴充套件KMP演算法

擴充套件kmp 擴充套件kmp可以用來解決很多字串問題,如求乙個字串的最長回文子串和最長重複子串。演算法 設next i 為滿足b i i z 1 b 0 z 1 的最大的z值 也就是b的自身匹配 設目前next 0 lenb 1 與ex 0 i 1 均已求出,要用它們來求ex i 的值。設p為目前...

擴充套件kmp演算法

原文章 拓展kmp是對kmp演算法的擴充套件,它解決如下問題 定義母串s,和字串t,設s的長度為n,t的長度為m,求t與s的每乙個字尾的最長公共字首,也就是說,設extend陣列,extend i 表示t與s i,n 1 的最長公共字首,要求出所有extend i 0 i 從而得知extend 0 ...