FZU - 2128 最长子串(KMP?)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq1059752567/article/details/62051237

问题很简单,给你一个字符串s,问s的子串中不包含s1,s2...sn的最长串有多长。
Input

输入包含多组数据。第一行为字符串s,字符串s的长度1到10^6次方,第二行是字符串s不能包含的子串个数n,n<=1000。接下来n行字符串,长度不大于100。

字符串由小写的英文字符组成。

Output
最长子串的长度
Sample Input
lgcstraightlalongahisnstreet
5
str
long
tree
biginteger
ellipse
Sample Output
12


听说strstr比kmp还快……但是权当把这道题练手kmp了

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;

const int maxn = 1e6 + 5;
int st[maxn], ed[maxn], tol = 0;
int Next[105];
void kmpinit(char x[], int m)
{
	int j = -1, i = 0;
	Next[0] = -1;
	while (i < m)
	{
		while (j != -1 && x[i] != x[j]) j = Next[j];
		Next[++i] = ++j;
	}
}

void kmp(char x[], int m, char y[], int n)
{
	int i = 0, j = 0;
	kmpinit(x, m);
	while (i<n)
	{
		while (j != -1 && x[j] != y[i]) j = Next[j];
		++i; ++j;
		if (j >= m)
		{
			st[tol] = i - m;
			ed[tol] = i - 1;
			tol++;
			j = Next[j];
		}
	}
}

char s[maxn], s1[105];
int main()
{
	while (scanf("%s", s) != EOF)
	{
		int n;
		scanf("%d", &n);
		tol = 0;
		for (int i = 0; i < n; i++)
		{
			scanf("%s", s1);
			kmp(s1, strlen(s1), s, strlen(s));
		}
		int ans = 0;
		st[tol] = ed[tol] = 0;
		sort(st, st + tol+1);
		sort(ed, ed + tol+1);
		st[0] = -1;
		ed[++tol] = strlen(s);
		for (int i = 1; i <= tol; i++)
			ans = max(ans, ed[i] - st[i - 1] - 1);
		cout << ans << endl;
	}
	return 0;
}



猜你喜欢

转载自blog.csdn.net/qq1059752567/article/details/62051237