18.12.20 DSA 最长公共子串

描述

给出n个由小写字母组成的字符串,求一个最长的字符串,它同时是这n个字符串的子串。

输入

第一行是一个整数n(1<=n<=5),表示输入字符串的个数。
接下来n行每行为一个由小写字母构成的字符串,每个字符串的长度至少为1,最长不超过2000。输出输出一行整数,为最长公共子串的长度。

样例输入

3
abcb
bca
acbc

样例输出

2

提示

数据范围
对于40%的数据,每个字符串的长度不超过200。来源POI 2000

 1 #include <iostream>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <stack>
 5 #include <string>
 6 #include <math.h>
 7 #include <queue>
 8 #include <stdio.h>
 9 #include <string.h>
10 #include <set>
11 #include <vector>
12 #include <fstream>
13 #define maxn 4005
14 #define inf 999999
15 #define cha 127
16 #define eps 1e-6
17 using namespace std;
18 
19 int Next[maxn];
20 int ans = 0, n,size0;
21 string line[6], cb;
22 
23 int findnext(int s) {
24     memset(Next, 0, sizeof(Next));
25     int i = s, k = -1+s, m = cb.length();
26     int Max = 0;
27     Next[i] = s-1;
28     while (i < m-1) {
29         while (k >= s && cb[i] != cb[k])
30             k = Next[k];
31         i++, k++;
32         Next[i] = k;
33         if(i-k+s+1>=size0)
34             Max = max(Max, k - s);
35     }
36     return Max;
37 }
38 
39 void init() {
40     scanf("%d", &n);
41     for (int i = 1; i <= n; i++)
42         cin >> line[i];
43     size0 = line[1].length();
44     for (int i = 0; i < size0; i++) {
45         int min0 = inf;
46         for (int j = 2; j <= n; j++) {
47             cb = line[1] +'-'+ line[j]+'-';
48             int tmp = findnext(i);
49             if (tmp <= ans)
50             {
51                 min0 = 0;
52                 break;
53             }
54             min0 = min(min0, tmp);
55         }
56         ans = max(min0, ans);
57     }
58     printf("%d\n", ans);
59 }
60 
61 int main() {
62     init();
63     return 0;
64 }
View Code

超级容易WA,满满的恶意……

WA点:

1)next数组要开两倍大小,不然RE

2)两个串拼起来的时候中间要有分隔符,不然算到的值很可能错误

3)findnext函数要仔细写,特别是终止循环条件那个数

4)

4
aaaa
sjdiwaaaa
aaaa
sjdiaaawdeji

4
aaaa
aaaaa
aaaaaa
aaa

猜你喜欢

转载自www.cnblogs.com/yalphait/p/10148594.html
dsa
今日推荐