Kmp找字符串循环节——Period ( POJ 1961 )

来源:互联网 发布:乎字的意义和用法 编辑:程序博客网 时间:2024/05/16 20:41
  • 题目链接:
    http://poj.org/problem?id=1961

  • 分析:
    给出一个字符串长度为N,从左变开始取2~N个字符出来构成一个新字符串,若新字符串能被一个最短的循环节构成则输出新字符串的长度和循环节循环次数。

  • 题解:
    直接用Kmp里的SetNext()函数,求出该字符串里每一个字符的重复位置,用2~N长度减去以该长度为下标对应Next数组里的值即重复位置得到该两个重复出现字符间的长度,若字符串长度能被该长度整除则说明这段长度的字符是字符串的最短循环节,就可以输出。

  • AC代码:

#include <iostream>#include <cstring>#include <cstdio>#include <queue>#include <algorithm>#include <cmath>using namespace std;char b[1234567];int Next[1234567];int cnt;int n;void SetNext()//子串的next数组,如果只看代码的话,很难得出值的确定方法。{    int i=0,j=-1;    Next[0]=-1;    while(i<n)    {        if(j==-1||b[i]==b[j])//b为模式数组        {            i++; j++;            Next[i]=j;        }        else        j=Next[j];    }}int main(){    int t = 1;    while(scanf("%d", &n) && n)    {        scanf("%s", b);        SetNext();        cout <<"Test case #" <<t++<<endl;        for(int i=1;i<=n;i++)//遍历各个长度的字符串找其循环节        {            //cout << Next[i] << endl;            int length = i-Next[i];  //循环节的长度            //cout << length << endl;            if(i != length && i % length == 0)                printf("%d %d\n", i, i/length);        }        printf("\n");    }    return 0;}
0 0
原创粉丝点击