字符串单元节(KMP中NEXT数组剖析)

来源:互联网 发布:mac iphone 蓝牙 网络 编辑:程序博客网 时间:2024/06/08 16:35

                                                     题目链接

上篇博客介绍了KMP算法
这次又用到了KMP算法中的NEXT数组
可以说NEXT数组的作用非常大,可以用于各种的求字符串的循环节
而这一题又如何用到了KMP中的NEXT数组
这道题求的是子循环串
正好!!和NEXT的意义相同
NEXT数组里面的数表示到此字符为止
前缀和后缀相同的长度为NEXT
这样我们拿当前的字符的序列(第一个字符是1,第二是2,依次递推)
减去NEXT  表示循环节长度,如果循环次数是整数那么就输出
如何判断循环次数是整数?如果字符的序列可以整除序列-NEXT,那么就是整数次循环
那么就输出
注意:若NEXT为0时不用考虑,NEXT为零表示没有相同的前缀后缀!那么就不存在循环!

#include<stdio.h>#include<string.h>#include<iostream>using namespace std;int nextnum[1000010];int main(){    string s;    int step=1,n;    while(cin>>n)    {        if(n==0)            break;        cin>>s;        if(step!=1)            printf("\n");        memset(nextnum,0,sizeof(0));        int i=0,j=1;        while(j<n)  //先写出next数组        {            if(s[i]!=s[j]&&i!=0)            {                i=nextnum[i-1];            }            else if(s[i]!=s[j]&&i==0)            {                nextnum[j]=0;                j++;            }            else if(s[i]==s[j])            {                nextnum[j]=i+1;                i++,j++;            }        }        for(int i=0;i<n;i++)        {            printf("%d ",nextnum[i]);        }        printf("Test case #%d\n",step++);        for(int i=0;i<n;i++)        {            int j=i+1-nextnum[i];            if((i+1)%j==0&&nextnum[i]!=0)            {                printf("%d %d\n",i+1,(i+1)/j);            }        }    }    return 0;}



原创粉丝点击