题目链接:http://poj.org/problem?id=3080
题目大意:给你N个长度为60的字符串(N<=10),求他们的最长公共子串(长度>=3)。
题目分析:KMP字符串匹配基础题。直接枚举第1个字符串的所有子串,判断这个子串是否出现在另外N-1个串中。
实现代码如下:
#include <cstdio> #include <string> #include <iostream> #include <algorithm> #include <vector> using namespace std; const int maxn = 66; int n, m, nxt[maxn]; string s, t; // s代表母串,t代表子串 int T, N; string ss[11]; vector<string> tt; void cal_next() { m = t.length(); for (int i = 0, j = -1; i < m; i ++) { while (j != -1 && t[j+1] != t[i]) j = nxt[j]; nxt[i] = (j+1 < i && t[j+1] == t[i]) ? ++j : -1; } } bool check_s_has_t() { n = s.length(); // cal_next(); for (int i = 0, j = -1; i < n; i ++) { while (j != -1 && t[j+1] != s[i]) j = nxt[j]; if (t[j+1] == s[i]) { j ++; if (j >= m-1) { return true; } } } return false; } bool cmp(string s, string t) { if (s.length() != t.length()) return s.length() > t.length(); return s < t; } int main() { cin >> T; while (T --) { cin >> N; for (int i = 0; i < N; i ++) cin >> ss[i]; tt.clear(); for (int i = 0; i < 60; i ++) { for (int j = 3; i+j <= 60; j ++) { string tmp_s = ss[0].substr(i, j); tt.push_back(tmp_s); // cout << "tmp: " << tmp_s << endl; } } sort(tt.begin(), tt.end(), cmp); bool findOne = false; for (int i = 0; i < tt.size(); i ++) { t = tt[i]; cal_next(); bool flag = true; for (int j = 1; j < N; j ++) { s = ss[j]; if (check_s_has_t() == false) { flag = false; break; } } if (flag == true) { findOne = true; break; } } if (!findOne) puts("no significant commonalities"); else cout << t << endl; } return 0; }
作者:zifeiy