扩展KMP
扩展KMP嘛。
不就是KMP+manachar而已啧。
要想了解扩展KMP那就必须先知道KMP。【KMP网址我会放在博客的最下面~
现在了解了KMP后,解释扩展KMP就简单了。
因为KMP是扩展KMP的基础。简单来说,扩展KMP是KMP+manachar。
扩展KMP是用来匹配两个字符串的前缀和后缀的,具体来讲就是求字符串A的所有后缀中和字符串B的最长公共前缀是什么或者说是多长
那么KMP的核心思想就是:next依旧是那个next但是得出next的方法就变成了manachar的方法。具体什么意思呢?就是记录一个next的最远端。如果当前询问的这个数字的next+它本身的位置在最远端范围内,那么就直接得出答案,如果不在范围内,就暴力得出next。接下来就用KMP的模式,求next的方法继续匹配另一个字符串。
就是KMP的模式,KMP的next,manachar的求法,KMP的原理。
嗯。没错,就是这么简单。
诶。我知道你们不信。放出我的一段(pi)程(ka)序(qiu)你们就知道了。
求next:
next[0]=m;
for (i=0;T[i]==T[i+1];i++);
next[1]=i; p=1;
for (i=2;i<m;i++) {
u=p+next[p]; //u为最右端位置
if (i+next[i-p]<u) next[i]=next[i-p];//如果答案可以直接取
else { //如果答案需要探索
for (j=max(u-i,0);T[i+j]==T[j];j++);
next[i]=j; p=i;
}
}
求ex(extand【扩展):
for (i=0;i<m&&S[i]==T[i];i++);
ex[0]=i; p=0;
for (i=1;i<n;i++) {
u=p+ex[p]; //u为最右端位置
if (i+next[i-p]<u) ex[i]=next[i-p]; //如果答案可以直接取得
else { //如果答案需要探索
for (j=max(u-i,0);j<=m&&S[i+j]==T[j];j++);
ex[i]=j; p=i;
}
}
你看,是不是一毛一样。
还是那个熟悉的模式,还是那个熟悉的next,还是那个manachar的方式。
哦!
对了,忘记讲时间复杂度了。这可是证明完全明白扩展KMP的证明啊!
。。。
其实跟manachar是一毛一样的,因为是一样的求法。因为它不管是暴力求还是根据之前已有的答案求,都会往前进。这就说明了它的时间复杂度是线性的,也就是N再加上前面求next的M次。所以就是O(N+M)。
so easy!
KMP详情见:http://blog.csdn.net/riven__/article/details/52142017
manachar详情见:http://blog.csdn.net/riven__/article/details/52148535