Live2d Test Env

Hihocoder 1625 : 重复字符串匹配 (KMP)

 

描述

给定两个字符串A和B,请你求出字符串A最少重复几次才能使得B是A的子串。  

例如A="hiho",B="hohihohi"。则A重复3次之后变为"hihohihohiho",这时B是A的子串。

输入

输入包含多组数据。  

第一行包含一个整数T,表示数据组数。 (1 ≤ T ≤ 5)  

对于每组数据,第一行包含一个字符串A,第二行包含一个字符串B。  

对于30%的数据,1 ≤ |A|, |B| ≤ 1000  

对于100%的数据, 1 ≤ |A|, |B| ≤ 100000 并且A和B都只包含小写字母。

输出

A最少重复的次数。如果无论重复多少次也不能包含B,输出-1。

样例输入

2
hiho  
hohihohi  
hiho  
coder

样例输出

3
-1

 

思路:一直重复A字符串(有上限),看是否可以达到k==lenb。

没必要枚举起点,一位任何一位A[i]都可以做起点,所以最多多加一个循环。 即次数不超过 ((lenb-1)/lena+1) +1 。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1000010;
int Next[maxn],ans;
char a[maxn],b[maxn];
void kmp()
{
    int k=0,lena=strlen(a+1),lenb=strlen(b+1);
    ans=-1;  Next[1]=0;
    for(int i=2;i<=lenb;i++){
        while(k&&b[i]!=b[k+1]) k=Next[k];
        if(b[i]==b[k+1]) k++;
        Next[i]=k;
    } 
    k=0;
    for(int p=1;p<=(lenb-1)/lena+2;p++){
       for(int i=1;i<=lena;i++){
          while(k&&a[i]!=b[k+1]) k=Next[k];
          if(a[i]==b[k+1]) k++;
          if(k==lenb) { ans=p; return ;}
       }   
    }
}
int main()
{
    int T; scanf("%d",&T);
    while(T--){
        memset(Next,0,sizeof(Next));
        scanf("%s%s",a+1,b+1);
        kmp();
        printf("%d\n",ans);
    } return 0;
}

 

posted @ 2018-02-17 21:10  nimphy  阅读(366)  评论(0编辑  收藏  举报