hdu 2203 亲和串(kmp)

时间:2023-01-03 19:20:00



Problem Description
人随着岁数的增长是越大越聪明还是越大越笨,这是一个值得全世界科学家思考的问题,同样的问题Eddy也一直在思考,因为他在很小的时候就知道亲和串如何判断了,但是发现,现在长大了却不知道怎么去判断亲和串了,于是他只好又再一次来请教聪明且乐于助人的你来解决这个问题。
亲和串的定义是这样的:给定两个字符串s1和s2,如果能通过s1循环移位,使s2包含在s1中,那么我们就说s2 是s1的亲和串。
 

Input
本题有多组测试数据,每组数据的第一行包含输入字符串s1,第二行包含输入字符串s2,s1与s2的长度均小于100000。
 

Output
如果s2是s1的亲和串,则输出"yes",反之,输出"no"。每组测试的输出占一行。
 

Sample Input
 
 
AABCD CDAA ASD ASDF
 

Sample Output
 
 
yes no
 

只要将母串重复一次再进行KMP匹配就行了,因为在重复母串的过程中,已经将循环后的所有可能都列举出来了.


  1.  
  2. #include <iostream>

    #include <stdio.h>

    #include <string.h>

    #include <queue>

    using namespace std;

    int Next[100011];

    char s1[100011];

    char s2[100011];

    void GetNext(char *s,int len)

    {

        Next[0]=-1;

        int i;

        int j=-1;

        while (i<len)

        {

            if(j==-1 || s[i]==s[j])

            {

                i++;

                j++;

                if(s[i]==s[j])

                    Next[i]=Next[j];

                else

                    Next[i]=j;

            }

            else

                j=Next[j];

        }

    }

    bool kmp(char *s1,int len1,char *s2,int len2)

    {

        int i=0;

        int j=0;

        while (i<len1 && j<len2)

        {

            if(s1[i]==s2[j]|| j==-1)

            {

                i++;

                j++;

            }

            else

                j=Next[j];

        }

        if(j==len2)

            return true;

        return false;

    }


    int main()

    {

        int len1,len2;

        while (scanf("%s",s1)!=EOF)

        {

            getchar();

            scanf("%s",s2);

            len1=strlen(s1);

            len2=strlen(s2);

            if(len2>len1) //这种情况肯定不行

            {

                puts("no");

                continue;

            }

            for (int i=len1,j=0; i<2*len1; i++,j++)

                s1[i]=s1[j];

            s1[2*len1]='\0';

            GetNext(s2, len2);

            printf(kmp(s1,2*len1, s2, len2)?"yes\n":"no\n");

        }

        return 0;

    }