hdu 2203 亲和串 (KMP)

亲和串
Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 17936    Accepted Submission(s): 7896

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

C/C++:

 1 #include <map>
 2 #include <queue>
 3 #include <cmath>
 4 #include <vector>
 5 #include <string>
 6 #include <cstdio>
 7 #include <cstring>
 8 #include <climits>
 9 #include <iostream>
10 #include <algorithm>
11 #define INF 0x3f3f3f3f
12 using namespace std;
13 const int my_max = 1e5 + 10;
14 
15 string s1, s2;
16 int my_next[my_max];
17 
18 bool my_kmp()
19 {
20     int len1 = s1.size(), len2 = s2.size(), temp = len2;
21     if (len1 < len2) return false;
22     for (int i = 1, j = 0; i < len2; ++ i)
23     {
24         while (j > 0 && s2[i] != s2[j]) j = my_next[j];
25         if (s2[i] == s2[j]) ++ j;
26         my_next[i + 1] = j;
27     }
28 
29     for (int i = 0, j = 0; i < len1; ++ i)
30     {
31         while (j > 0 && s2[j] != s1[i]) j = my_next[j];
32         if (s2[j] == s1[i]) ++ j;
33         if (j == len2) return true;
34     }
35 
36     return false;
37 }
38 
39 int main()
40 {
41     ios::sync_with_stdio(false);
42     memset(my_next, 0, sizeof(my_next));
43     while (cin >>s1)
44     {
45         cin >>s2;
46         if (s1.size() < s2.size())
47         {
48             printf("no
");
49             continue;
50         }
51         s1 = s1 + s1.substr(0, s1.size() - 1);
52 
53         if (my_kmp()) printf("yes
");
54         else printf("no
");
55     }
56     return 0;
57 }
原文地址:https://www.cnblogs.com/GetcharZp/p/9516125.html