【kmp】 字符串最大周期

大侠住店

TimeLimit: 1 Second MemoryLimit: 32 Megabyte

Totalsubmit: 116 Accepted: 64

Description

有一天晚上,一位大侠打败了若干个武林高手,一时高兴就到一家客栈喝了很多酒,以至于烂醉如泥。最后大侠不得不在这个客栈休息,但是这个店里的老板是一个很迷信的人,他认为半夜住点的人可能是一些妖魔鬼怪的化身,因此这个时间他会很小心。同时他知道妖魔鬼怪不会算法。因此每当晚上有人住店的时候,他就会出一个问题问他们,如果答对就证明他不是妖魔鬼怪,就同意住店。如果答不对就可能是妖魔鬼怪,就不同意住店。今天他出了这样一个问题,给出一个字符串,找出这个字符串有多少个周期(最多)。现在大侠特别想住店休息,请你帮他解决这个问题。

Input

第一行是一个整数 t (t<=10),表示测试的组数。
接下来t行,每行一个字符串,长度小于10000.

Output

总共t行,第i行是一个整数,表示第i组的周期。

Sample Input

2
ababab
ababa

Sample Output

3
1

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define N 10002
int next[N];
char s[N];
void get_next(int len)
{
    int i = 0;
    int j = -1;
    next[0] = -1;
    while (i < len)
    {
        if (j == -1 || s[i] == s[j])
        {
            ++i;
            ++j;
            next[i] = j;
        }
        else j = next[j];
    }
    return ;
}

int main()
{
    //freopen("in.txt","r",stdin);
    int num;
    cin >> num;
    while (num--)
    {
        scanf("%s", s);
        int len=strlen(s);
        get_next(len);
        int t=len-next[len];
        if(len%t!=0)cout <<1 <<endl;
        else cout << len/t <<endl;
    }
    return 0;
} 

poj 3461 ac代码如下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX=10000+10;
char a[MAX],b[1000000];
int next[MAX];
void get_next(char *a){
 int i=-1,j=0,len=strlen(a);
 next[0]=-1;
 while(j<len){
  if(i == -1 || a[i] == a[j])
  {
   i++;
   j++;
   if(a[i] == a[j])
                next[j]=next[j];
   else next[j]=i;
  }
  else i=next[i];
 }
 return;
}
int KMP(char *a,char *b){
 get_next(a);
 int i=0,j=0,num=0,lena=strlen(a),lenb=strlen(b);
 b[lenb]='#';
 while(j<=lenb){//不需要i<lena,要把b全部比较完
  if(i == -1 || a[i] == b[j])++i,++j;
  else{//
   if(i == lena)++num;//表示有一个a
   i=next[i];
  }
 }
 return num;
}

int main(){
// freopen("in.txt","r",stdin);
 int n;
 cin>>n;
 while(n--){
  cin>>a>>b;
  cout<<KMP(a,b)<<endl;
 }
 return 0;
}
  另一种模板:
#include<stdio.h>
#include <iostream>
#include <memory.h>
using namespace std;
char A[1000005],B[10005];
int next[10005];
void getnext()
{
    int i,j;
    next[0]=0;
    for(i=1,j=0;B[i];i++)
    {
        while(j>0 && B[i]!=B[j])
        j=next[j-1];
        if(B[i]==B[j])
        j++;
        next[i]=j;
    }
}
int KMP()
{
    int i,j,ans;
    for(i=j=ans=0;A[i];i++)
    {
        while(j>0 && A[i]!=B[j])
        j=next[j-1];
        if(A[i]==B[j])
        {
            j++;
            if(!B[j])
            {
                j=next[j-1];
                ans++;
            }
        }
    }
    return ans;
}
int main()
{
//    freopen("in.txt","r",stdin);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s%s",B,A);
        memset(next,0,sizeof(next));
        getnext();
        printf("%d
",KMP());
    }
    return 0;
}

 

原文地址:https://www.cnblogs.com/balfish/p/4015094.html