福州大学第十届校赛 & fzu 2128最长子串

时间:2024-01-04 09:28:38

思路: 对于每个子串,求出 母串中 所有该子串 的 开始和结束位置,保存在 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);
}
}