• 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
  • 相关阅读:
    ibatis的优缺点及可行性分析
    NHibernate优点和缺点:
    IbatisNet的介绍和使用
    bat(续七)-for语句(循环结构)
    bat(续五)-获取批处理文件所在路径
    Shell函数参数
    Shell函数:Shell函数返回值、删除函数、在终端调用函数
    Shell break和continue命令
    Shell until循环
    Shell while循环
  • 原文地址:https://www.cnblogs.com/gongxijun/p/3477759.html
Copyright © 2020-2023  润新知