马上就要搞常规了,有更新一点博客的必要了(似乎并是没有什么逻辑....其实省掉了重要原因....1.串学的差不多了,2.博客这更新速度慢得....)
【KMP及其拓展】
KMP算法。十分经典,当然stl党&strstr党也是可以轻松水过的。
这个算法的目的就是判断一个串是否为另一个串的子串,当然根据这个算法当中所涉及到的辅助数组也有周期的一些性质。
http://codeplay0314.gitcafe.io/2015/04/19/KMP/
具体思想&next[]数组的由来,请猛戳链接【帮同学打广告也是应该的】(一定要耐心&细心的看完哦....)
现在假设我们亲爱的读者已经明白了KMP的思想&明白了next[]的意义。
下面来说一个性质设A串的长度为len,设T=len-next[len],同时Len%T==0,则一定有A串为一个周期串,而且T为其最大循环串的长度。
然后就是扩展KMP,这个东西是什么意思呢?
就是给你两个串S,T,定义ex[i]表示串 S[i...lenS]与串T的最长公共前缀长度,目标是求出ex[]。
可能还不太清楚,那就给个样例:S: ydcydc T: ydcismygod
ex[0]=3表示S串从0开始向后的串与T串的最长公共前缀为"ydc"长度为3,ex[1]=0,表示S串从1开始向后与T串最长公共前缀为空,长度为0
同理,我们就求出了ex[]的后面几项:
ex[0]=3,ex[1]=0,ex[2]=0,ex[3]=3,ex[4]=0,ex[5]=0,ex[6]=3
所以对于这个问题,我们该怎么做呢?我们发现这个东西和KMP很像。(因为它叫扩展KMP(雾),因为它们都和前缀这个东西有关)。
可是S串从每一个位置向后的串(其实就是S的后缀)都一定是互不相同的,难道我们要每一位都去比?NoNoNo....
因为它们都是和T串比,我们只要利用T串来保存这些后缀之间的信息就好了。下面将直接阐述。
首先我们定义两个变量,k和p,其中p=k+ex[k],而k则是所有已知的ex[i]中 (i+ex[i]) 最大的一个i。
那么我们就可以通过这两个东西推出我们现在需要求的ex[i]了。
首先给一个标出了以上变量的图:
其中也将T串标出来了,其中绿色的部分表示两个串相同的一段。
现在我们再定义一个next[]数组,这是啥呢?就是T串的ex[]数组。
也顺便回顾一遍ex[]的定义,next[i]表示T[i...lenT]与[1...lenT]的最长公共前缀。
好了,我们设L=next[i-k],那么会出现两种情况:
情况一:
情况二:
啊,区别就是红色线段的长度= =...
如果越过了p,当然我们就需要暴力比较黄色和粉红色的部分,如果没有越过,恩,那么ex[i]=next[i-k]啦...
未完待续....