码迷,mamicode.com
首页 > 其他好文 > 详细

KMP(最长重复子串 & 最小覆盖)

时间:2014-08-13 19:04:47      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:kmp   最长重复子串   最小覆盖   

转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents



如果一个长度 L 字符串是由 n 个长度 L / n 串构成的。那么最后一个字符的next值是L-L/n吧;



例如:

一个字符串:abbabbabbabbabb(一共15个字符)
next[15]=12吧!
我们拿:15 - 12 = 3 就是最长重复子串的长度
现在说一般情况:
假设 next[length] = k
如果 k % length == 0 那 length / k 就是最长重复串长度;
如果 k 不能整除 length 那最长重复串就是它自己了。

KMP,next[]表示模式串如果第i位(设T[0]为第0位)与文本串第j位不匹配,则要回到第next[i]位继续与文本串第j位匹配。则模式串第1位到next[n]与模式串第n-next[n]位到n位是匹配的。所以思路和上面一样,如果n%(n-next[n])==0,则存在重复连续子串,长度为n-next[n]。

例如:    a    b    a    b    a    b

next: -1   0    0    1    2    3    4

next[n] == 4代表着:前缀abab与后缀abab相等的最长长度,这说明,ab这两个字母为一个循环节,长度 = n-next[n];


求next[]值的代码如下:


#include<cstdio>
#include<cstring>
#define N 1000017
int next[N];
int len;
void getnext(char T[])
{
    int i = 0, j = -1;
    next[0] = -1;
    while(i < len)
    {
        if(j == -1 || T[i] == T[j])
        {
            i++;
            j++;
            next[i] = j;
        }
        else
            j = next[j];
    }

}
int main()
{
    char s[N];
    while(~scanf("%s",s))
    {
         len = strlen(s);
        getnext(s);
        for(int i = 1; i <= len; i++)
        {
            printf("%d ",next[i]);
        }
        printf("\n");
    }
    return 0;
}


实例运用见:http://blog.csdn.net/u012860063/article/details/38532507



bubuko.com,布布扣

KMP(最长重复子串 & 最小覆盖),布布扣,bubuko.com

KMP(最长重复子串 & 最小覆盖)

标签:kmp   最长重复子串   最小覆盖   

原文地址:http://blog.csdn.net/u012860063/article/details/38537503

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!