给定一个字符串,求它最多由几个循环节构成。

思路:很自然地想到要求这个字符串最少后移几位后与自己匹配

#include <cstdio>
#include <cstring>

#define MX 10000001

using namespace std;

char src[MX],tar[MX];
int nxt[MX];

void getnext(int len)
{
    int j=0;
    nxt[0]=0;
    for(int i=1;i<len;i++)
    {
        while(j>0&&src[j]!=src[i])j=nxt[j-1];
        if(src[i]==src[j])j++;
        nxt[i]=j;
    }
}

int kmp(int lent,int lens)
{
    int i=0,j=0;
    while(i<lent&&j<lens)
    {
        if(tar[i]==src[j])i++,j++;
        else
        {
            if(j==0)i++;
            else j=nxt[j-1];
        }
        if(j==lens)return i-j;
    }
    return -1;
}

int main()
{
    int tlen,slen;
    while(scanf("%s",src))
    {
        if(src[0]=='.'&&strlen(src)==1)break;
        memset(tar,0,sizeof(tar));
        strcat(tar,src+1),strcat(tar,src);
        slen=strlen(src),tlen=strlen(tar);
        getnext(slen);
        printf("%d\n",slen/(kmp(tlen,slen)+1));
    }
    return 0;
}
分类: 所有

3 条评论

litble · 2017年4月24日 8:55 下午

我是在批判这个算法…..不仅仅是代码长度的问题,这个算法的复杂度也不够优化啊。

    boshi · 2018年3月8日 10:17 下午

    明明都是O(n),而且我能求出所有的循环节。

      konnyakuxzy · 2018年3月8日 10:36 下午

      Orz您太强了
      我现在才做这道题
      而且还恬不知耻地发了题解QvQ
      我太弱了

发表评论

电子邮件地址不会被公开。 必填项已用*标注

你是机器人吗? =。= *