分析:第一想法就是把字符串s1循环移位一次,然后判断s2是否为移位后的s1的子串,KMP实现的,但是仔细一想这样存在在严重的缺陷,比如字符串s1=“abc”,s2=“abcabcabcabcabc”,理论上,这是符合亲和串的定义的,但我在完全没考虑这种可能的情况下也AC了,这能说明这题的数据量小。
KMP实现代码如下:
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define maxn 1000005
int nex[maxn];
char s1[maxn*2],s2[maxn];
void get_nex(char s[])//获得模式串s的next数组
{
int i=0, j=-1;
nex[0]=-1;
int len=strlen(s);
while(i<len)
{
if(j==-1||s[i]==s[j])
{
i++;
j++;
if(s[i]!=s[j]) nex[i]=j;
else nex[i]=nex[j];
}
else j=nex[j];
}
}
void solve()
{
get_nex(s2);
int len=strlen(s1);
strncpy(s1+len,s1,len);
len*=2;
int len2=strlen(s2);
int i=0,j=0;
bool flag=0;
while(i<len)
{
if(j==-1||s1[i]==s2[j])
{
i++;
j++;
}
else j=nex[j];
if(j==len2)
{
flag=1;
break;
}
}
if(flag) puts("yes");
else puts("no");
}
int main()
{
while(scanf("%s%s",s1,s2)!=-1)
solve();
return 0;
}
其实本题还有一种更为简单的解法,直接用string库里的strstr函数即可。
实现代码如下:
#include <cstring>
#include <iostream>
#include <cstdio>
using namespace std;
#define maxn 1000005
char str[maxn],str1[maxn],str2[2*maxn];
int main()
{
while ( gets(str) )
{
gets(str1);
strcpy(str2, str);
strcat(str2, str); //直接strcat的话会出错
if(strstr(str2, str1)) puts("yes");
else puts("no");
}
return 0;
}