• 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
    ",ans);
        } return 0;
    }
  • 相关阅读:
    LC 1383. Maximum Performance of a Team
    P3805 【模板】manacher算法
    P1226 【模板】快速幂||取余运算
    1119 Pre- and Post-order Traversals
    1117 Eddington Number (二分)
    1111 Online Map (Dij/spfa)
    1108 Finding Average
    IPC
    Json to JObject转换的使用方法
    JsonConvert序列化
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8452180.html
Copyright © 2020-2023  润新知