poj2406——Power Strings

来源:互联网 发布:钱规则网络剧 编辑:程序博客网 时间:2024/05/20 05:45

题目大意:给出一个字符串,问它最多由多少个相同的字符串(单个字符)组成

输入:(可以有很多case,各占一行,输入以 . 结束)

            第i个case的字符串(字符串长度为1~1000000)

            .

输出:相同字符串的个数

分析:KMP算法的应用。

           得到next[]数组的函数就不多说了,实在不理解背下来应用好了。

           这道题要找循环节的个数,所以字符串长度n除以循环节长度肯定是个整数,否则不存在循环节。

           next[i]的意思就是模式串(本题中的字符串)中的第i位与文本串的第j位匹配不上时就移到模式串第next[i]位继续与文本串第j位匹配。注意next[]数组从next[1]也就是模式串第一位开始。

           next[n]就是整个模式串的前后缀最大匹配长度,n-next[n]就是循环节长度。

           如果有循环节,也就是说n%(n-next[n])=0,就输出n%(n-next[n]),循环节长度为n-next[n];否则(不能整除循环节长度),说明原字符串中没有循环节,输出1。

代码:转载自https://www.cnblogs.com/ziyi--caolu/archive/2013/01/01/2841708.html

#include<iostream>
#include<string.h>
using namespace std;
int next[1000005];
char s[1000005];
void getnext()
{
    int i=0,j=-1;
    next[0]=-1;
    int len=strlen(s);
    while(i<len)
    {
        if(s[i]==s[j]||j==-1)
        {
            i++;
            j++;
            next[i]=j;
        }
        else
            j=next[j];
    }
}
int main()
{
    while(scanf("%s",s)>0)
    {
        if(s[0]=='.')
            break;
        int len=strlen(s);
        getnext();
        if(len%(len-next[len])==0)
            printf("%d\n",len/(len-next[len]));
        else
            printf("1\n");
    }
    return 0;
}