扩展 KMP

扩展KMP解决这样一些问题:
给定两个字符串 S 和 T(长度分别为 n 和 m),下标从 0 开始,定义extend[i]等于S[i]...S[n-1]与 T 的最长相同前缀的长度,求出所有的extend[i]。
时间复杂度(n+m)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
const int MAXN=2e6+5;
char s[MAXN],t[MAXN];
int nxt[MAXN],extend[MAXN];
void getnxt(){
	int id=0,mx=0;
	int len=strlen(t);
	nxt[0]=len;
	for(int i=1;i<len;i++){
		if(i>=mx||i+nxt[i-id]>=mx){
			if(i>=mx) mx=i;
			while(mx<len&&t[mx]==t[mx-i]) mx++;
			nxt[i]=mx-i;
			id=i;
		}else nxt[i]=nxt[i-id];
	}
}
void getext(){
	getnxt();
	int id=0,mx=0;
	int len1=strlen(s),len2=strlen(t);
	for(int i=0;i<len1;i++){
		if(i>=mx||i+nxt[i-id]>=mx){
			if(i>=mx) mx=i;
			while(mx<len1&&s[mx]==t[mx-i]) mx++;
			extend[i]=mx-i;
			id=i;
		}else extend[i]=nxt[i-id];
	}
}
int main(){
	freopen("in.txt","r",stdin);
	while(~scanf("%s %s",s,t)){
		getext();
		cout << "next:   ";
		int m=strlen(t),n=strlen(s);
        for (int i = 0; i < m; i++)
            cout << nxt[i] << " ";
        cout << "
extend: ";
        for (int i = 0; i < n; i++)
            cout << extend[i] << " ";

        cout << endl << endl;
	}
	fclose(stdin);
	return 0;
}
原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8001080.html