标签: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