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 }
View Code

 

你可能感兴趣的:(HDU)