标签:style blog class code tar ext
问题描述:给出模板串A和子串B,长度分别为lenA和lenB,要求在线性时间内,对于每个A[i](0<=i<lenA),求出A[i..lenA-1]与B的最长公共前缀长度,记为ex[i](或者说,ex[i]为满足A[i..i+z-1]==B[0..z-1]的最大的z值)。扩展KMP可以用来解决很多字符串问题,如求一个字符串的最长回文子串和最长重复子串。需要严重注意的是:在上述的情况(2)中,本该从A[p+1]与B[p-i+1]开始匹配,但是,若p+1<i,也就是p-i+1<0(这种情况是有可能发生的,当ex[i-1]=0,且前面的ex值都没有延伸到i及以后的时候)的话,需要将A、B的下标都加1(因为此时p必然等于i-2,如果A、B的下标用两个变量x、y控制的话,x和y都要加1)!!!!!
代码:
int next[maxn],extend[maxn]; //extend[i]表示原串以第i开始与模式串的前缀的最长匹配
void EKMP(char s[],char t[])//s[]为主串,t[]为模版串
{
int i,j,p,l;
int len=strlen(t);
int len1=strlen(s);
memset(next,0,sizeof(next));
memset(extend,0,sizeof(extend));
next[0]=len;
j=0;
while(1+j<len&&t[j]==t[1+j])j++;
next[1]=j;
int a=1;
for(i=2; i<len; i++)
{
p=next[a]+a-1;
l=next[i-a];
if(i+l<p+1)next[i]=l;
else
{
j=max(0,p-i+1);
while(i+j<len&&t[i+j]==t[0+j])j++;
next[i]=j;
a=i;
}
}
j=0;
while(j<len1&&j<len&&s[j]==t[j])j++;
extend[0]=j;
a=0;
for(i=1; i<len1; i++)
{
p=extend[a]+a-1;
l=next[i-a];
if(l+i<p+1)extend[i]=next[i-a];
else
{
j=max(0,p-i+1);
while(i+j<len1&&j<len&&s[i+j]==t[j])j++;
extend[i]=j;
a=i;
}
}
}代码来源:点击打开链接
文字来源:点击打开链接
这些理论性的东西,看到一半实在是看不下去啦,,抓狂抓狂,,,,还是通过做题目来理解理论分析吧。。。做到相应的题目在加到本博文中吧。
HDU 1195 Open the Lock,布布扣,bubuko.com
标签:style blog class code tar ext
原文地址:http://blog.csdn.net/zmx354/article/details/25296337