扩展Kmp

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

  

原文地址:https://www.cnblogs.com/cutemush/p/12356503.html