字符串匹配—KMP 扩展KMP Manacher
kuangbin字符串专题传送门--http://acm.hust.edu.cn/vjudge/contest/view.action?cid=70325#overview
算法模板:
KMP:
const int MAXM=10010; const int MAXN=1000010; int a[MAXN],b[MAXM],Next[MAXM]; int n,m; void getNext(int b[],int Next[]) { int j=0,k=-1; Next[0]=-1; while(j<m-1) { if(k==-1||b[j]==b[k]) //匹配 { j++,k++; Next[j]=k; } else k=Next[k]; //不匹配 } } int KMP(int a[],int b[]) { int i=0,j=0; getNext(b,Next); while(i<n) { if(j==-1||a[i]==b[j]) i++,j++; else j=Next[j]; if(j==m) return i-m+1; } return -1; }
扩展KMP:
const int MAXN; int Next[MAXN],extend[MAXN]; char a[MAXN],b[MAXN]; void getNext(char b[]) { int i,len=strlen(b); Next[0]=len; for(i=0;i<len-1&&b[i]==b[i+1];i++) { Next[1]=i; int tmp=1; for(int k=2;k<len;k++) { int p=tmp+Next[tmp]-1,L=Next[k-tmp]; if((k-1)+L>=p) { int j=(p-k+1)>0?(p-k+1):0; while(k+j<len&&b[k+j]==b[j]) j++; Next[k]=j,tmp=k; } else Next[k]=L; } } } void getExtend(char a[],char b[]) { memset(Next,0,sizeof(Next)); getNext(b); int lena=strlen(a),lenb=strlen(b),tmp=0; int minlen=lena<lenb?lena:lenb; while(tmp<minlen&&a[tmp]==b[tmp]) tmp++; extend[0]=tmp,tmp=0; for(int k=1;k<lena;k++) { int p=tmp+extend[tmp]-1,L=Next[k-tmp]; if((k-1)+L>=p) { int j=(p-k+1)>0?(p-k+1):0; while(k+j<lena&&j<lenb&&a[k+j]==b[j]) j++; extend[k]=j,tmp=k; } else extend[k]=L; } }
Manacher:
const int MAXN=110010; char s1[MAXN],Mt[MAXN*2]; int Mp[MAXN*2]; int Manacher(int len,char s[]) { int Mx=0,id=0,L=0; int ret=0; Mt[L++]='$';Mt[L++]='#'; for(int i=0;i<len;i++) { Mt[L++]=s[i]; Mt[L++]='#'; } Mt[L]=0; for(int i=1;i<L;i++) { if(Mx>i) Mp[i]=min(Mp[id*2-i],Mx-i); else Mp[i]=1; while(Mt[i+Mp[i]]==Mt[i-Mp[i]]) Mp[i]++; if(Mp[i]+i>Mx) { Mx=Mp[i]+i; id=i; } if(Mp[i]-1>ret) ret=Mp[i]-1; } return ret; }