亲和串
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
题意描述:
判断两个字符串s1,s2是否满足s1通过循环移位包含s2.
解题思路:
利用kmp当循环查找当查到相同时标记,跳出循环;当i=lena时即i将主串走过一遍后,i=0从头继续查找实现循环移位,当第二遍i又找到lena时结束跳出循环,若还没有出现子串,输出no;
#include<stdio.h>
#include<string.h>
int main()
{
char a[100010],b[100010];
int lena,lenb,i,j,next[100010],flag,h;
while(gets(a)!=NULL)
{
gets(b);
lena=strlen(a);
lenb=strlen(b);
j=0;
next[0]=0;
//求出b的next[]数组
for(i=1;i<=lenb-1;)
{
if(j==0&&b[i]!=b[j])
{
next[i]=0;
i++;
}
if(b[i]==b[j])
{
next[i]=j+1;
i++;
j++;
}
if(j>0&&b[i]!=b[j])
{
j=next[j-1];
}
}
flag=0;
h=0;
for(i=0,j=0;;)
{
if(a[i]==b[j])
{
j++;
if(j==lenb)
{
flag=1;
break;
}
i++;
}
if(h==1&&i==lena)//第二次又查找完时,结束循环
break;
if(h==0&&i==lena)//当第一次字符串a查完时,i变为0
{
i=0;
h=1;
}
if(j==0&&a[i]!=b[j])
i++;
//因在循环中又两个i++,在哪个后边查找完都有可能所以判断了两次
if(h==0&&i==lena)//当第一次字符串a查完时,i变为0
{
i=0;
h=1;
}
if(j>0&&a[i]!=b[j])
j=next[j-1];
}
if(flag==1)
printf("yes\n");
else
printf("no\n");
}
}