【模板】扩展KMP

https://blog.csdn.net/dyx404514/article/details/41831947

定义和KMP不一样,同时程序实现非常复杂。建议背下来。主要是利用 d p dp dp的思想。

时间复杂度证明:每个点只会被枚举一次。所以是 O ( n ) O(n) O(n)

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
char a[N],b[N];
int nxt[N],ex[N];
void get_nxt(char *str) {
	int i,j=0,po,len=strlen(str);
	nxt[0]=len;
	while(str[j]==str[j+1]&&j+1<len) j++;
	nxt[1]=j;
	po=1;
	for(int i=2;i<len;i++) {
		//we can not equal
		if(nxt[i-po]+i<nxt[po]+po)//这里隐含着p>i 
		    nxt[i]=nxt[i-po];
		else {
			j=nxt[po]+po-i;
			if(j<0) j=0;
			while(i+j<len&&str[i+j]==str[j]) j++;
			nxt[i]=j;
			po=i;
		}
	}
}
void exkmp(char *s1,char *s2) {
	int i,j=0,po,l1=strlen(s1),l2=strlen(s2);
	get_nxt(s2);
	while(s2[j]==s1[j]&&j<l1&&j<l2) j++;
	ex[0]=j;
	po=0;
	for(int i=1;i<l1;i++) {
		//strange:po=0 -> i-po=i???
		//it seems that 相比上一个,少处理了一个
		//but nxt[0] is meaningless
		//it must be ex[po]
		//because string is different
		//it must be nxt[i-po]
		//because string is the same
		//we can not equal
		if(nxt[i-po]+i<ex[po]+po)//这里隐含着p>i 
		    ex[i]=nxt[i-po];
		else {
			j=ex[po]+po-i;
			if(j<0) j=0;
			while(i+j<l1&&j<l2&&s1[i+j]==s2[j]) j++;
			ex[i]=j;
			po=i;
		}
	}
}
int main() {
	scanf("%s %s",a,b);
	exkmp(a,b);
	for(int i=0;i<strlen(a);i++) printf("%d ",ex[i]);
}
posted @ 2020-12-12 17:04  仰望星空的蚂蚁  阅读(11)  评论(0)    收藏  举报  来源