亲和串 kmp

  

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
 
模板
#include<bits/stdc++.h>
using namespace std;
//input
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);i--)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m);
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define inf 0x3f3f3f3f
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
 #define N 100000+5
 int nex[N];
 int lenp,lens;
 string s,p;
 void getnext()
 {
     nex[0]=-1;
     int k=-1,j=0;
     while(j<lenp-1)
     {
         if(k==-1||p[j]==p[k])
            nex[++j]=++k;
         else k=nex[k];
     }
 }
 void kmp()
 {
     int j=0;
     int i=0;
     while(i<lens&&j<lenp)
     {
         if(s[i]==p[j]||j==-1)
         {
             i++;
             j++;
         }
         else
            j=nex[j];
         if(j==lenp)
         {
             printf("yes
");return ;
         }
     }
     printf("no
");
     return ;
 }
 int main()
 {
     while(cin>>s>>p)
     {
         s=s+s;
         lens=s.size();
         lenp=p.size();
         getnext();
         kmp();
     }
     return 0;
 }
 
原文地址:https://www.cnblogs.com/bxd123/p/10673018.html