[数据结构]KMP小结

KMP小结 

By Wine93 2013.9


1.学习链接



2.个人小结

(1).KMP在字符串中匹配中起着巨大作用,可以在O(n+m)内完成

(2).要充分理解next 数组,其求法和next数组的含义(最长后缀等于最长前缀),了解其用途,下面我就next数组在求字符串最小周期中的应用举例

(2.1).什么是字符串最小周期?

Ex:字符串ababab,最小周期为2,ab

Ex:字符串abcd,最小周期为4,abcd

(2.2)最小周期的一个性质

如果len%(len-next[len])==0,则该字符串的最小周期为len-next[len]

(2.3)性质的证明


欲证:若len%(len-next[len])==0, 则该字符串的最小周期为len-next[len]  (len表示该字符串长度)

        证:我们分2部分证

① 若len%(len-next[len])==0len-next[len]为字符串s的周期  

② 证明len-next[len]就是其最小周期

因为next数组的含义是最长后缀等于最长前缀,所以s[ 1……next[len] ]

s[next[len]+1……len ]是相等的,如上图,线段(1)和线段(2)相等

因为len%(len-next[len])==0,所以我们把线段(2)可以平均分成很多等份(图中假设为4),每份长度都为s1,线段(1)也可以分成同等份,如上图,根据next数组的定义,s1=s2,又因为s2=s3,s3=s4….所以依次类推可得s1=s2=s3=s4=s5=s6=s7=s8,所以,s1是字符串s的周期,所以①得证

len-next[len]不是其最小周期,也就是说存在更小的长度是字符串s的周期,也就是说next[len]要变大(也就是说最长前缀等于最长后缀的值要增大),而根据next数组的定义,next[len]就是已经是最大值(已经是最长前缀等于最长后缀),所以相互矛盾,所以②得证

综上所述如果len%(len-next[len])==0,则该字符串的最小周期为len-next[len] (len表示该字符串长度)


3.相关题

(1)循环节相关 

POJ 2406 Period 

HDU 3746 Cyclic Nacklace

CF 182D Common Divisors 

(2)Next数组

HDU 3336 Count the string

HDU 2594 Simpsons’ Hidden Talents

(3)KMP匹配

HDU 1711 Number Sequence 

CF 8A Train and Peter (string::find也可以)


4.KMP模板

# include<cstdio>
# include<cstring>
# include<vector>
# include<algorithm>
using namespace std;

# define VI vector<int>
# define N 200005
int Next[N];

void getnext(char *s)
{
	int i,j,len=strlen(s);
	Next[0]=j=-1;
	for(i=1;i<len;i++)
	{
		while(j>=0&&s[j+1]!=s[i]) j=Next[j];
		if(s[j+1]==s[i]) j++;
		Next[i]=j;
	}
}

VI kmp(char *s,char *ch)
{
	int i,j,len=strlen(s),m=strlen(ch);
	VI ans;
	ans.clear();
	getnext(ch);
	j=-1;
	for(i=0;i<len;i++)
	{
		while(j>=0&&ch[j+1]!=s[i]) j=Next[j];
		if(ch[j+1]==s[i]) j++;
		if(j+1==m) ans.push_back(i-m+1);
	}
	return ans;
}


5.总结

总结:KMP的应用很大,一定要深入理解,尤其是next数组这对处理字符串匹配问题有着重大影响,AC自动机就是基于KMP来实现的.同时也要理解next数组的局限性(只能是后缀与前缀的对应关系),这对解题时的判断有着重要作用 

注:后缀数组可以解决KMP的一部分局限性




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值