POJ3080 Blue Jeans 题解 KMP算法

痞子三分冷 提交于 2019-12-03 11:42:12

题目链接: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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!