ZZ:http://willem.linshihan.cn/1293.html
//扩展 KMP 算法 (2018.2.21) /* S |_______|____________________|______|_________| 0 a i p Slen-1 T |______|_____________|______|_______| 0 p-i i-a p-a Tlen-1 nxt[i-a]? 设 S[a, p) 与 T[0, p - a) 匹配, 则当 S[p] != T[p - a] 时, 若 1) i + nxt[i - a] < p, 则 lcp[i] = nxt[i - a] 2) i + nxt[i - a] == p, 则从 S[p] 和 T[p - i] 开始往后暴力比较 3) i + nxt[i - a] > p, 则 lcp[i] = p - i */ #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; char S[1000005], T[1000005]; int Slen, Tlen, nxt[1000005], lcp[1000005]; int main(){ while(scanf("%s%s", S, T) != EOF){ Slen = strlen(S), Tlen = strlen(T); nxt[0] = Tlen; for(register int i = 1, a = 0, p = 0; i < Tlen; i++) { if(i + nxt[i - a] >= p) { if(i > p) //有可能输入的两个字符串完全不相等,那p的值就要等于i //也就是说始终间将第一个字符串的第i个字符与第二个字符串的第一个字符开始比 //p代表从前比较时,最靠左的失效位置, 在我们的讨论中一直认为i<p,所以当i>p时,p=i //于是从从前的失效位置开始比较,即从t[p]开始与t[p-i]开始比较, p = i; while(p < Tlen && T[p] == T[p - i]) p++; nxt[i] = p - i, a = i; } else nxt[i] = nxt[i - a]; } for(register int i = 0, a = 0, p = 0; i < Slen; i++){ if(i + nxt[i - a] >= p){ if(i > p) p = i; while(p < Slen && S[p] == T[p - i]) p++; lcp[i] = p - i, a = i; } else lcp[i] = nxt[i - a]; } for(register int i = 0; i < Slen - 1; i++) printf("%d ", lcp[i]); printf("%d ", lcp[Slen - 1]); } return 0; }
https://blog.csdn.net/qq_40679299/article/details/80609308
https://blog.csdn.net/qq_40938077/article/details/82048643
https://segmentfault.com/a/1190000008663857
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=9999; int Next[maxn]; int extand[maxn]; //s的后缀与t的最长公共前缀。 void getnext(char* t) { int i,len=strlen(t); Next[0]=len; for(i=0;i<len-1&&t[i]==t[i+1];i++); Next[1]=i; int a=1; for(int k=2;k<len;k++){ int p=a+Next[a]-1,l=Next[k-a]; if(k+l-1>=p){ //l>=p-k+1 int j=max(p-k+1,0); while(k+j<len&&t[k+j]==t[j]) j++; Next[k]=j;a=k; }else Next[k]=l; } } void getextend(char* s,char* t) { memset(Next,0,sizeof(Next)); getnext(t); int slen=strlen(s),tlen=strlen(t),a=0; int minlen=min(slen,tlen); while(a<minlen&&s[a]==t[a]) a++; extand[0]=a,a=0; for(int k=1;k<slen;k++){ int p=a+extand[a]-1,l=Next[k-a]; if(k+l-1>=p){ int j=max(p-k+1,0); while(k+j<slen&&j<tlen&&s[k+j]==t[j]) j++; extand[k]=j;a=k; }else extand[k]=l; } } int main() { char s[maxn],t[maxn]; while(scanf("%s%s",s,t)!=EOF){ getextend(s,t); for(int i=0,len=strlen(t);i<len;i++) printf("%d ",Next[i]); puts(""); for(int i=0,len=strlen(s);i<len;i++) printf("%d ",extand[i]); puts(""); } } ———————————————— 版权声明:本文为CSDN博主「Combatting」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_40679299/article/details/80609308