HDU(2594)kmp算法next数组的理解与使用。


http://acm.hdu.edu.cn/showproblem.php?pid=2594

这里有一点要注意,前缀必须要从头开始算,后缀要从最后一个数开始算,中间截一段相同字符串是不行的。

再回到next[i]的定义,对于串ptr = "ababaaababaa";

next[0] = -1,代表着除了第一个元素,之前前缀后缀最长的重复子串,这里是空 ,即"",没有,我们记为-1,代表空。(0代表1位相同,1代表两位相同,依次累加)。

next[1] = 0,即“a”,没有前缀与后缀,故最长重复的子串是空,值为-1;

next[2] = 0,即“ab”,前缀是“a”,后缀是“b”,最长重复的子串“”;

next[3] = 1,即"aba",前缀是“ab”,后缀是“ba”,最长重复的子串“a”;next数组里面就是最长重复子串字符串的个数

next[4] = 2,即"abab",前缀是“aba”,后缀是“bab”,最长重复的子串“ab”;

next[5] = 3,即"ababa",前缀是“abab”,后缀是“baba”,最长重复的子串“aba”;

next[6] = 1,即"ababaa",前缀是“ababa”,后缀是“babaa”,最长重复的子串“a”;

next[7] = 1,即"ababaaa",前缀是“ababaa”,后缀是“babaaa”,最长重复的子串“a”;

next[8] = 2,即"ababaaab",前缀是“ababaaa”,后缀是“babaaab”,最长重复的子串“ab”;

next[9] = 3,即"ababaaaba",前缀是“ababaaab”,后缀是“babaaaba”,最长重复的子串“aba”;

next[10] = 4,即"ababaaabab",前缀是“ababaaaba”,后缀是“babaaabab”,最长重复的子串“abab”;

next[11] = 5,即"ababaaababa",前缀是“ababaaabab”,后缀是“babaaaababa”,最长重复的子串“ababa”;

next[12]= 1, 即"ababaaababaa"!!!!!!!

#include<bits/stdc++.h>
using namespace std;
const int maxn=600010;
char s1[maxn*2],s2[maxn];
int nxt[maxn*2];
void getnext(char *a)
{
    int i=-1,j=0;
    int len=strlen(a);
    nxt[0]=-1;
    while(j<len)
    {
        if(i==-1||a[i]==a[j])
        {
            j++;
            i++;
            nxt[j]=i;
        }
        else
            i=nxt[i];
    }
}
int main()
{
    while(cin>>s1>>s2)
    {
        int lena=strlen(s1),lenb=strlen(s2),len=lena+lenb;
        strcat(s1,s2);
        getnext(s1);
        //  for(int i=0;i<=len;i++)
        //cout<<nxt[i]<<" ";
        while(nxt[len]>lena||nxt[len]>lenb)
            //例如 ababb   aababba 合起来ababbaababba next[11]=6;
            //next[6]=1
            len=nxt[len];
        len=nxt[len];
        for(int i=0; i<len; ++i)cout<<s1[i];
        if(len)cout<<' ';
        cout<<len<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/beposit/article/details/80686933
今日推荐