字符串专题

马上就要搞常规了,有更新一点博客的必要了(似乎并是没有什么逻辑....其实省掉了重要原因....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]啦...

  

未完待续....

posted @ 2015-08-22 21:20  诚叙  阅读(211)  评论(0编辑  收藏  举报