HDUOJ---(2203)亲和串

时间:2022-05-05
本文章向大家介绍HDUOJ---(2203)亲和串,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

亲和串

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6579    Accepted Submission(s): 2976

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

Author

Eddy

采用的是kmp算法思想,只是由于当做一个环来处理,比如前面的AABCD--->AABCDAABCD这样处理就可以了。但是用数组的话求余就可以更好的实现...

有关kmp算法,其实大部分内容还是BF算法的知识,只是添加了一个next数组,来安排匹配串t不匹配时回溯的位置,而主串是不回溯的.....

求next数组的代码:

 1 void get_next(char const * pt , int  * next)
 2 {
 3   int i,j=-1,len=strlen(pt);
 4   next[i=0]=-1;
 5 while(i<len)
 6 {
 7  if(j==-1||pt[j]==pt[i])
 8  { 
 9   ++i;
10   ++j;
11  if(pt[j]!=pt[i])
12         next[i]=j;
13 else
14  next[i]=next[j];
15  }
16 else
17 j=next[j];
18 }
19 }

有了上面这个函数,下面的kmp部分其实就是BF算法; 代码如下:

 1 //next设置为全局变量数组,当然也可以设置下面数组中...
 2 int smatch_kmp(char *ps,char *pt )
 3 {
 4 int lens=strlen(ps);   //sizoef(pt)/sizeof(char);
 5 int lent=strlen(pt);
 6 int i=0,j=-1;
 7 //next[]
 8 get_next(ps,next);
 9        while(i<lens&&j<lent)
10      {
11         if(j==-1||ps[i]==pt[j])
12          {
13             ++i;
14             ++j;
15           }
16           else
17             j=next[j];
18      }
19      if(j==lent)
20   return i-lent;
21 else
22    return -1;
23 
24 }

所以此题的代码不难想到了为:

代码:

 1 //BF个改进kmp算法....
 2 /*@code龚细军*/
 3 #include<stdio.h>
 4 #include<string.h>
 5 #define maxn 100000
 6 int next[maxn+1];
 7 char pps[maxn+1],ppt[maxn+1];
 8 /*求next数组的值*/
 9 void getnext(char const *pt ,int *next)   //t表示目标串  s代表的是主串
10 {
11     int i=0,j=-1;
12     next[i]=-1;
13     int len=strlen(pt);
14     while(i<len)
15     {
16         if(j==-1||pt[i]==pt[j])  //匹配的情况,或者是开始的赋值
17         {
18             i++;
19             j++;
20             if(pt[i]!=pt[j])   //再次判断是否匹配
21             {
22                 next[i]=j;
23             }
24             else
25                 next[i]=next[j];
26         }
27         else
28          j=next[j];
29     }
30 }
31 //BF的改进kmp
32 bool smatch_kmp(char const *s ,char const *t)
33 {
34     int lens=strlen(s);       //到主串的长度
35     int lent=strlen(t);      //得到目标串的长度
36     memset(next,0,sizeof(next));
37     getnext(ppt,next);
38     int i=0,j=-1;
39     while(i<2*lens&&j<lent)
40     {
41         if(j==-1||s[i%lens]==t[j])   //目前匹配所以都进位i++,j++
42         {
43             i++;
44             j++;
45         }
46         else j=next[j];    //如果是BF的话,需要回溯,再j++ ,但是kmp在此处作出了改进,不必全回溯
47     }
48     if(j>=lent)
49        return 1;     // i-lent; 说明是匹配成功了..
50     else
51         return 0;     //说面并未匹配成功
52 
53 }
54 
55 int main()
56 {
57 
58     while(scanf("%s%s",pps,ppt)!=EOF)
59         puts(smatch_kmp(pps,ppt)==true?"yes":"no");
60     return 0;
61 }