概述
参考资料:
给出模板串A和子串B,长度分别为lenAlenA和lenBlenB,要求在线性时间内,对于每个A[i]A[i](0<=i<lenA)(0<=i<lenA)
求出A[i..lenA−1]A[i..lenA−1] 与B的最长公共前缀长度,记为ex[i]ex[i](或者说,ex[i]ex[i]为满足A[i..i+z−1]==B[0..z−1]A[i..i+z−1]==B[0..z−1]的最大的z值)。
扩展KMP可以用来解决很多字符串问题,如求一个字符串的最长回文子串和最长重复子串。
(1)头文件
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int MAXN = 2000010; 4 int Next[MAXN]; 5 int extend[MAXN];
(2)EXKMP
1 void EKMP(char s[],char t[])//s为主串,t为模板串 2 { 3 int i,j,p,L; 4 int slen = strlen(s); 5 int tlen = strlen(t); 6 Next[0] = tlen; 7 j = 0; 8 while(j+1 < tlen && t[j] == t[j+1]) 9 j++; 10 Next[1] = j; 11 12 int a = 1; 13 for(i = 2;i < tlen;i++) 14 { 15 p = Next[a]+a-1; 16 L = Next[i-a]; 17 if(i+L<p+1) 18 Next[i]=L; 19 else 20 { 21 j=max(0,p-i+1); 22 while(i+j < tlen && t[i+j] == t[j]) 23 j++; 24 Next[i] = j; 25 a = i; 26 } 27 } 28 29 j = 0; 30 while(j < slen && j < tlen && s[j] == t[j])j++; 31 extend[0] = j; 32 a = 0; 33 for(i = 1;i < slen;i++) 34 { 35 p = extend[a]+a-1; 36 L = Next[i-a]; 37 if(L+i < p+1) 38 extend[i] = L; 39 else 40 { 41 j = max(0,p-i+1); 42 while(i+j<slen && j < tlen && s[i+j] == t[j]) 43 j++; 44 extend[i] = j; 45 a = i; 46 } 47 } 48 }
补充
- extend[i]extend[i]表示原串以第ii开始与模式串的前缀的最长匹配
经典题目: