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 }

 

转载于:https://www.cnblogs.com/yongze103/archive/2010/07/19/1780911.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值