POJ 3080 KMP练手题

思路是枚举第一个字符串中所有长度大于三的字串,再用KMP在其他串中验证是否存在这个字串,取最长字母序最小者

代码:

  1 #include<stdio.h>
  2 #include<iostream>
  3 using namespace std;
  4 
  5 #include<math.h>
  6 #include<algorithm>
  7 #include<string.h>
  8 #include<stdlib.h>
  9 #include<vector>
 10 #include<set>
 11 #include<map>
 12 #include<stack>
 13 #include<string>
 14 #include<queue>
 15 
 16 #define repA(p,q,i)  for( int (i)=(p); (i)!=(q); ++(i) )
 17 #define repAE(p,q,i)  for( int (i)=(p); (i)<=(q); ++(i) )
 18 #define repD(p,q,i)  for( int (i)=(p); (i)!=(q); --(i) )
 19 #define repDE(p,q,i)  for( int (i)=(p); (i)>=(q); --(i) )
 20 
 21 void MAIN();
 22 
 23 char str[11][100];
 24 char ans[100];
 25 char tmp[100];
 26 int pi[110];
 27 bool KMP(char *p, char *t);
 28 void getPI(char *p);
 29 
 30 int main()
 31 {
 32     //freopen("1111.in", "r", stdin);
 33     //freopen("1111.out", "w", stdout);
 34     MAIN();
 35     //fclose(stdout);
 36     
 37     return 0;
 38 }
 39 
 40 void MAIN()
 41 {
 42      int test;  scanf("%d", &test);
 43      while(test--)
 44      {
 45           int n;  scanf("%d", &n);
 46           for(int i=0; i<n; ++i)
 47           {
 48             scanf("%s", str[i]);
 49             //printf("%s\n", str[i]);
 50           }
 51           
 52           ans[0] = '\0';
 53           
 54           int len = strlen(str[0]);
 55           int end;
 56           //cout<<len<<endl;
 57           for(int sub = 3; sub <=len; ++sub) 
 58           {
 59               //cout<<sub<<endl;
 60               end = len-sub;
 61               for(int s = 0; s <= end; ++s)
 62               {
 63                   //cout<<s;
 64                   for(int k = 0; k<sub; ++k)
 65                     tmp[k] = str[0][s+k];
 66                   
 67                   tmp[sub] = '\0';
 68                   //printf("%s\n", tmp);
 69                   bool flag = true;
 70                   for(int i=1; i<n; ++i)
 71                   {
 72                     //cout<<"OK"<<endl;
 73                     if(! KMP(tmp, str[i]) )
 74                     {
 75                         flag = false;
 76                         break;     
 77                     } 
 78                   }
 79                   //cout<<sub<<endl;
 80                   if(flag)
 81                   {
 82                      // cout<<"OK"<<endl;
 83                       int tq = strlen(ans);
 84                       if(sub > tq)
 85                         strcpy(ans, tmp);
 86                       else if(sub == tq)
 87                       {
 88                            if(strcmp(ans, tmp) > 0)
 89                              strcpy(ans, tmp);     
 90                       }
 91                         
 92                   }
 93                        
 94               }        
 95           }
 96           
 97           if(strlen(ans) < 3)  printf("no significant commonalities\n");
 98           else printf("%s\n", ans);
 99                        
100      }
101      
102      return ;          
103 }
104 
105 bool KMP(char *p, char *t)
106 {
107      getPI(p);
108      //cout<<"PIOK";
109      int n = strlen(t);
110      int m = strlen(p);
111      
112      int q=0;
113      repA(0,n,i)
114      {
115           while(q>0 && p[q] != t[i])
116             q = pi[q-1];
117           if(p[q] == t[i])
118             ++q;
119           if(q == m)
120             return true;
121                      
122      } 
123      //cout<<"KMPOK"<<endl;
124      return false;     
125 }
126 
127 void getPI(char *p)
128 {
129      pi[0] = 0;
130      int k=0;
131      int m = strlen(p);
132      repA(1, m, q)
133      {     
134          
135          while(k>0 &&  p[k]!=p[q])
136            k = pi[k-1];
137          if(p[k] == p[q])
138            ++k;
139          pi[q] = k;
140          
141      }   
142      
143      return ;  
144 }
View Code

 

posted on 2014-04-11 17:09  码农之上~  阅读(166)  评论(0)    收藏  举报

导航