擴充套件KMP演算法

2022-05-13 20:53:52 字數 1571 閱讀 5975

(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

【核心**】

lena = strlen(a); lenb =strlen(b);

next[

0] = lenb; next[1] = lenb - 1

; re(i, lenb-1) if (b[i] != b[i + 1])

int j, k = 1

, p, l;

re2(i,

2, lenb)

}int minlen = lena <= lenb ? lena : lenb; ex[0] =minlen;

re(i, minlen)

if (a[i] != b[i])

k = 0

; re2(i,

1, lena)

}

【時間複雜度分析】

在kmp和擴充套件kmp中,不管是a串還是b串,其匹配位置都是單調遞增的,故總時間複雜度是線性的,都為o(lena + lenb)(只是擴充套件kmp比kmp的常數更大一些)。

【應用】

kmp和擴充套件kmp在解決字串問題中有大用。很多看上去很猥瑣的字串問題,都可以歸結到這兩種演算法之中。另外,這裡的「字串」可以延伸為一切型別的陣列,而不僅僅是字元陣列。

c/c++模板

#include

using

namespace

std;

const

int n = 101010

;int

next[n],extand[n];

void getnext(char *t)

else next[k] =l;

} }void getextand(char *s,char *t)

else extand[k] =l;

}}int

main() }/*

aaaabaaa aaaa

*/

擴充套件KMP演算法

擴充套件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...

擴充套件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為目前...