Blue Jeans--POJ 3080

1、题目类型:字符串、暴力法、KMP算法。

2、解题思路:寻找最长的公共子串,STL中string部分方法的应用。

3、注意事项:string.h中库函数的调用,KMP匹配。

4、实现方法: (暴力法)

  
    
1 #include < iostream >
2 #include < string >
3 using namespace std;
4
5 string str[ 10 ];
6
7 int check( int nStr, string s)
8 {
9 int i;
10 for (i = 1 ; i < nStr; i ++ )
11 {
12 // string的find()函数当没有找到相应子串时返回sting::npos
13 if (str[i].find(s) == string ::npos)
14 return 0 ;
15 }
16 return 1 ;
17 }
18
19 string gene( int nStr)
20 {
21 int len, j;
22 string longest;
23 for (len = str[ 0 ].length(); len >= 3 ; len -- )
24 {
25 for (j = 0 ; j <= str[ 0 ].length() - len; j ++ )
26 {
27 string substring = str[ 0 ].substr(j, len); // 从j开始获得len长度的字符串
28 if (check(nStr, substring))
29 // 对比新旧获得子串
30 if (substring.size() > longest.size() || (substring.size() == longest.size() && substring < longest))
31 longest = substring;
32 }
33 }
34 return longest;
35 }
36
37 void Seach( int nStr)
38 {
39 string substring = gene(nStr);
40 if (substring.size())
41 cout << substring << endl;
42 else cout << " no significant commonalities " << endl;
43 }
44 int main()
45 {
46 int nCase;
47 int nStr, i;
48 cin >> nCase;
49 while (nCase -- )
50 {
51 cin >> nStr;
52 for (i = 0 ; i < nStr; i ++ )
53 cin >> str[i];
54 Seach(nStr);
55 }
56 return 0 ;
57 }
58

 

 

4、实现方法: (KMP)

  
    
1 #include < iostream >
2 #include < string >
3 using namespace std;
4
5 const int N = 70 ,M = 15 ;
6 int ls,lp,pre[N],len;
7 char str[M][N],s2[N],ans[N];
8
9 void prefix( char * p)
10 {
11 int i, k;
12 memset(pre, 0 , sizeof (pre));
13 pre[ 1 ] = 0 ;
14 k = 0 ;
15 for (i = 2 ;i <= lp;i ++ )
16 {
17 while (k > 0 && p[k + 1 ] != p[i])
18 k = pre[k];
19 if (p[k + 1 ] == p[i]) k ++ ;
20 pre[i] = k;
21 }
22 }
23
24 bool kmp( char * p, char * s)
25 {
26 int i,k,cnt = 0 ;
27 k = 0 ;
28 for (i = 1 ;i <= ls;i ++ )
29 {
30 while (k > 0 && p[k + 1 ] != s[i])
31 k = pre[k];
32 if (p[k + 1 ] == s[i])
33 k ++ ;
34 if (k == lp)
35 return true ;
36 }
37 return false ;
38 }
39
40 int main()
41 {
42 int casenum, strnum, i, j;
43 cin >> casenum;
44 while (casenum -- )
45 {
46 cin >> strnum;
47 for (i = 0 ; i < strnum; i ++ )
48 cin >> str[i] + 1 ;
49 len = 0 ;
50 strcpy(ans, " no significant commonalities " );
51 for (lp = 60 ;lp >= 3 ;lp -- )
52 {
53 for (i = 1 ;i + lp - 1 <= 60 ;i ++ )
54 {
55 prefix(str[ 0 ] + i - 1 );
56 ls = 60 ;
57 for (j = 1 ;j < strnum;j ++ )
58 {
59 if ( ! kmp(str[ 0 ] + i - 1 ,str[j]))
60 break ;
61 }
62 if (j >= strnum && lp >= len)
63 {
64 strncpy(s2,str[ 0 ] + i,lp);
65 s2[lp] = 0 ;
66 if (lp > len || lp == len && strcmp(s2,ans) < 0 )
67 strcpy(ans, s2);
68 }
69 }
70 if (strcmp(ans, " no significant commonalities " ) != 0 )
71 break ;
72 }
73 puts(ans);
74 }
75 return 0 ;
76 }

 

你可能感兴趣的:(poj)