hdu 1867(A + B for you again) KMP的应用 /hdu 2594(Simpsons’ Hidden Talents) KMP

今天对KMP的认识又加深一点了,可是又不是很能用语言来表达!

题目大意:给定两个字符串,比如abcd,dcab,需要把它连接起来,但是需要遵循两个条件,1 最短原则   2  长度相同的前提下字典序的优先

连接原则:如果第一个字符串的后缀(长度为n)和第二个字符串的前缀(长度为n)相同,那么连接的时候可以省去相同的n个字符,本来有2n个字符;

仍然以上面的两个字符串为例,有两种连法,abcdcab和dcabcd,显然第二个字符串更短,所以输出dcabcd;

解决办法:两次KMP

运用一次KMP可以计算出两个字符串的前缀和后缀的相同长度n;

两次KMP后比较n的值即可;

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 #define N 100005
 6 char s1[N],s2[N];
 7 int next[N];
 8 void get_next(char *str)
 9 {
10     int i=0,j=-1;
11     next[0]=-1;
12     int len=strlen(str);
13     while(i<len)
14     {
15         if(j==-1||str[i]==str[j])
16         {
17           i++;
18           j++;
19           next[i]=j;
20         }
21           else
22             j=next[j];
23 
24     }
25 
26 
27 }
28 int KMP(char *str1,char *str2,int next[])
29 {
30     int i=0,j=0;
31     int len1=strlen(str1);
32 //    int len2=strlen(str2);
33     while(i<len1)//这里循环的应用根据不同的要求可以计算出符合条件的J值
34     {
35 //i要循环到len1而不是按照KMP的算法要求j,是因为我们需要计算str1的末尾
36         if(j==-1||str1[i]==str2[j])
37         {
38 
39             i++;
40             j++;
41         }
42         else
43             j=next[j];
44 
45     }
46     return j;
47 
48 }
49 int  main()
50 {
51     while(scanf("%s %s",s1,s2)!=EOF)
52     {
53 
54          memset(next,0,sizeof(next));
55          get_next(s2);
56          int c_1=KMP(s1,s2,next);
57          memset(next,0,sizeof(next));
58          get_next(s1);
59          int c_2=KMP(s2,s1,next);
60          if(c_1==c_2)
61          {
62 
63              if(strcmp(s1,s2)<0)
64              {
65 
66                  printf("%s%s\n",s1,s2+c_1);
67              }
68              else
69              {
70 
71                  printf("%s%s\n",s2,s1+c_2);;
72 
73              }
74          }
75          else{
76                 if(c_1>c_2)
77                 {
78                     printf("%s%s\n",s1,s2+c_1);
79 
80                 }
81                 else{
82                          printf("%s%s\n",s2,s1+c_2);
83                 }
84          }
85 
86 
87 
88     }
89     return 0;
90 
91 }

 hdu 2594 (Simpsons’ Hidden Talents)

和上面的题目一样只是没有上面那一题复杂,只需要一次KMP即可;

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 #define N 50004
 6 char s1[N],s2[N];
 7 int next[N];
 8 int len1,len2;
 9 void get_next()
10 {
11 
12     int i=0,j=-1;
13     next[0]=-1;
14     while(i<len1)
15     {
16 
17         if(j==-1||s1[i]==s1[j])
18         {
19             i++;
20             j++;
21             next[i]=j;
22 
23         }
24         else
25             j=next[j];
26     }
27 }
28 int KMP()
29 {
30 
31     int i=0,j=0;
32     get_next();
33     while(i<len2)
34     {
35         if(j==-1||s2[i]==s1[j])
36         {
37 
38             i++;
39             j++;
40         }
41         else
42             j=next[j];
43 
44     }
45     return  j;
46 }
47 int main()
48 {
49 
50   while(scanf("%s",s1)!=EOF)
51   {
52       len1=strlen(s1);
53       scanf("%s",s2);
54       len2=strlen(s2);
55       memset(next,-1,sizeof(next));
56       int ans;
57       ans=KMP();
58      // printf("%d\n",ans);
59       if(ans==0)
60         printf("0\n");
61       else
62       {
63           int i;
64           for(i=0;i<ans;i++)
65           {
66               printf("%c",s1[i]);
67           }
68           printf(" %d\n",ans);
69       }
70 
71 
72 
73 
74 
75   }
76   return 0;
77 }

 

 

你可能感兴趣的:(hidden)