POJ3450最长公共子串【kmp】

题目链接:http://poj.org/problem?id=3450

题目大意:给定n个长度不超过200的字符串,n < 4000。求这些字符串的最长公共子串,若没有,则输出 “IDENTITY LOST”。

思路:

1.枚举第一个字符串的各个子串s,将s分别与其他字符串进行kmp,来找到可以取得的s的最大长度(这样就是一次枚举中所有字符串的公共子串),然后接着枚举子串s,更新这个长度,注意在长度相等时选取字典序小即可。

2.strcmp(a, b)比较a, b字符串,返回值为0则字符串相同。返回值大于0则a的字典序大于b的字典序,返回值小于0则a的字典序小于b的字典序。

3.strcpy(a, b)将b字符串复制给a,strncpy(a, b, len)将b字符串前len个长度的字符复制给a,注意需要手动给a添加结束符 '\0'.

代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 const int inf = 0x3f3f3f3f;
 5 using namespace std;
 6 
 7 char str[4100][210], s[210], res[210], tt[210];
 8 int next[210], temp, s_len, str_len, flag;
 9 
10 void get_next()
11 {
12     s_len = strlen(s);//模式串 
13     next[0] = -1;
14     int j = 0, k = -1;
15     while(j < s_len)
16     {
17         if(k == -1 || s[j] == s[k])
18         {
19             j ++, k ++;
20             next[j] = k;
21         }
22         else
23             k = next[k];
24     }
25 }
26 
27 void kmp(int id)
28 {
29     temp = 0;
30     str_len = strlen(str[id]);
31     int i = 0, j = 0; //i文本串 j模式串 
32     int vis = 0;
33     while(i < str_len && j < s_len)
34     {
35         if(s[j] == str[id][i] || j == -1)
36         {
37             vis = 1;
38             i ++, j ++;
39         }
40         else
41             j = next[j];
42         temp = max(temp, j);
43     }
44     if(!vis)
45         flag = 0;
46 }
47 
48 int main()
49 {
50     int n, minn, ans_len, xx;
51     while(scanf("%d", &n) != EOF)
52     {
53         if(n == 0)
54             break;
55         getchar();
56         ans_len = -1;
57         for(int i = 0; i < n; i ++)
58             scanf("%s", str[i]);
59         int len = strlen(str[0]);
60         for(int i = 0; i < len; i ++)
61         {
62             minn = inf, xx = 0;
63             strcpy(s, str[0] + i);
64             get_next();
65             flag = 1;
66             for(int j = 1; j < n; j ++)
67             {
68                 kmp(j);
69                 if(flag == 0)
70                 {
71                     xx = 1;
72                     break;
73                 }
74                 minn = min(minn, temp);
75             }
76             if(xx == 1)
77                 continue;
78             if(minn > ans_len)
79             {
80                 ans_len = minn;
81                 strncpy(res, s, ans_len);
82                 res[ans_len] = '\0';
83             }
84             if(minn == ans_len)
85             {
86                 strncpy(tt, s, minn);
87                 tt[minn] = '\0';
88                 if(strcmp(res, tt) > 0)
89                     strcpy(res, tt);
90             }
91         }
92         if(ans_len == 0 || ans_len == -1)
93             printf("IDENTITY LOST\n");
94         else
95             printf("%s\n", res);
96     }
97     return 0;
98 }
View Code

 

posted @ 2019-07-18 13:39  缘未到  阅读(473)  评论(0编辑  收藏  举报