思路: 对于每个子串,求出 母串中 所有该子串 的 开始和结束位置,保存在 mark数组中,求完所有子串后,对mark数组按 结束位置排序,然后 用后一个的结束位置 减去 前一个的 开始 位置 再 减去 1,记录最大值
比如 aaaqwer 1 aaa 那么 最长为 aaqwer
用strstr判断子串是否存在于母串中。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1000005; struct MARK { int begin, end; bool operator <(const MARK& cmp) const { return end < cmp.end; } } mark[maxn]; char s[maxn], t[1005][105]; int n, cnt, next[105]; void work(const char str[], const char sub[]) { //memset(next, 0, sizeof(next)); //get_next(sub, next); int exp = 0, from, len = strlen(sub); while (strstr(str + exp, sub) != NULL) { from = strstr(str + exp, sub) - str; mark[cnt].begin = from; mark[cnt].end = from + len - 1; cnt++; exp = from + len - 1; } } int main() { while (scanf("%s", s) == 1) { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%s", t[i]); cnt = 0; for (int i = 0; i < n; i++) { work(s, t[i]); } mark[cnt].begin = mark[cnt].end = strlen(s); cnt++; sort(mark, mark + cnt); int ans = -1; for (int i = 0; i < cnt - 1; i++) { int len = mark[i + 1].end - mark[i].begin - 1; if (len > ans) ans = len; } printf("%d\n", ans == -1 ? strlen(s) : ans); } }
用KMP判断子串是否存在于母串中。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1000005; struct MARK { int begin, end; bool operator <(const MARK& cmp) const { return end < cmp.end; } } mark[maxn]; char s[maxn], t[1005][105]; int n, cnt, next[105]; void get_next(const char *sub, int *next) { int len = strlen(sub); int i, k; next[0] = k = -1; for (i = 0; i < len;) { if (k == -1 || sub[i] == sub[k]) { k++; i++; if (sub[k] != sub[i]) next[i] = k; else next[i] = next[k]; } else k = next[k]; } } int KMP(const char *str, const char *sub, const int *next) { int i, j; int len1 = strlen(str), len2 = strlen(sub); for (i = 0, j = 0; i < len1 && j < len2;) { if (j == -1 || str[i] == sub[j]) { i++; j++; } else j = next[j]; } if (j == len2) return i - len2; return -1; } void work(const char str[], const char sub[]) { //memset(next, 0, sizeof(next)); get_next(sub, next); int exp = 0, from = 0, len = strlen(sub); while ((from = KMP(str + exp, sub, next)) != -1) { mark[cnt].begin = from + exp; mark[cnt].end = from + exp + len - 1; cnt++; exp += from + len - (len == 1 ? 0 : 1); } } int main() { while (scanf("%s", s) == 1) { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%s", t[i]); cnt = 0; for (int i = 0; i < n; i++) { work(s, t[i]); } // for (int i = 0; i < cnt; i++) // printf("%d %d\n", mark[i].begin, mark[i].end); mark[cnt].begin = mark[cnt].end = strlen(s); cnt++; sort(mark, mark + cnt); int ans = -1; for (int i = 0; i < cnt - 1; i++) { int len = mark[i + 1].end - mark[i].begin - 1; if (len > ans) ans = len; } printf("%d\n", ans == -1 ? strlen(s) : ans); } }