HDU 1867 A + B for you again 字符匹配

解题报告:给你两个字符串,让你连接起来,没有前后顺序,要求是长度最短优先,其次是字典序最小。这题我用的是KMP,做两次匹配,分别把第一次跟第二次输入的字符串放前面,然后比较两次得到的字符窜的长度和字典序。

 1 #include<cstdio>
 2 #include<cstring>
 3 const int MAX = 200000+5; //因为如果两个加一起就有可能超出了,干脆开两倍的数组 
 4 int next[MAX];
 5 void get_next(const char *t) {
 6     next[0] = -1;
 7     int len = strlen(t);
 8     int i = 0,j = -1;
 9     while(i<len-1) {
10         if(j == -1 || t[i] == t[j]) {
11             i++;
12             j++;
13             next[i] = j;
14         }
15         else j = next[j];
16     }
17  //   next[0] = 0; // 将第一个next标记为-1,后面有用 
18 }
19 void KMP(char *s,const char *t) {
20     get_next(t);
21     int len1 = strlen(s);
22     int len2 = strlen(t);
23     int i = 0,j = 0;
24     if(len1 > len2)
25     i = len1 - len2;
26     while(i < len1 && j<len2) {
27         if(j == -1||s[i] == t[j]) { //这里j==0和j==-1有区别,只有第一个才是-1 ,而0有很多个 
28             i++;
29             j++;
30         }
31         else j = next[j];
32     }
33     strcpy(s+len1,t+j);
34 }
35 
36 int main() {
37     char T[MAX],S1[MAX],S2[MAX];
38     while(scanf("%s%s",S1,S2)!=EOF) {
39         strcpy(T,S1);
40         KMP(S1,S2);
41         KMP(S2,T);
42         int len1 = strlen(S1);
43         int len2 = strlen(S2);
44         if(len1<len2)
45         printf("%s\n",S1);
46         else if(len1>len2)
47         printf("%s\n",S2);
48         else {
49             int flag = strcmp(S1,S2);
50             if(flag == 1)
51             printf("%s\n",S2);
52             else printf("%s\n",S1);
53         }
54     }
55     return 0;
56 }
View Code

 

posted @ 2013-08-01 15:16  xiaxiaosheng  阅读(193)  评论(0编辑  收藏  举报