最大跨距

题解:

KMP即可。先用第一个串从头开始匹配,再反转标准串和第二个串,再匹配一次,然后用两个位置处理出答案,细节就是该怎么减和-1的判断。注意读入用getchar,我用gets要1000ms+,用getchar直接0ms。

简谈一下KMP,先处理出短串的Next数组,即最长相同前后缀长度,方便我们匹配失败后直接跳到下一个相同开头的地方。

然后再用类似的方法匹配标准串,利用Next数组可以在匹配失败的时候直接跳到下一个符合条件的地方,大幅缩短匹配时间。

时间复杂度O(0)

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#define MAXA 100005
using namespace std;
char Std[MAXA],S1[MAXA],S2[MAXA],Temp;
int StdLen,Len1,Len2,pos,Next[MAXA],k,Left = -1,Right = -1;
bool Flag;
int main() {
//	freopen("dis.in","r",stdin);
//	freopen("dis.out","w",stdout);
	while((Temp = getchar()) && Temp != ',')
	   Std[StdLen++] = Temp;
	while((Temp = getchar()) && Temp != ',')
	   S1[Len1++] = Temp;
	while((Temp = getchar()) && Temp != '\n')
	   S2[Len2++] = Temp;
	
	if(Len1 + Len2 > StdLen) {
		printf("-1");
		return 0;
	}
	Next[0] = k = -1;
	for(int i=1;i<Len1;i++) {
		while(k > -1 && S1[k + 1] != S1[i])
		      k = Next[k];
		if(S1[k + 1] == S1[i])
		   k++;
		Next[i] = k;
	} 
	k = -1;
	for(int i=0;i<StdLen;i++) {
		while(k > -1 && Std[i] != S1[k + 1])
		   k = Next[k];
		if(S1[k + 1] == Std[i])
		   k++;
		if(k == Len1 - 1) {
			Left = i - Len1 + 1;
			break;
		}
	}
	reverse(Std,Std + StdLen);
	reverse(S2,S2 + Len2);
	memset(Next,0,sizeof(Next));
	Next[0] = k = -1;
	for(int i=1;i<Len2;i++) {
		while(k > -1 && S2[k + 1] != S2[i])
		      k = Next[k];
		if(S2[k + 1] == S2[i])
		   k++;
		Next[i] = k;
	} 
	k = -1;
	for(int i=0;i<StdLen;i++) {
		while(k > -1 && Std[i] != S2[k + 1])
		   k = Next[k];
		if(S2[k + 1] == Std[i])
		   k++;
		if(k == Len2 - 1) {
			Right = i - Len2 + 1;
			break;
		}
	}
	//cout << Left << " " << Right << endl;
	if(Left == -1|| Right == -1 || Left + Len1 - 1 + Len2 + Right > StdLen) {
		printf("-1");
		return 0;
	}
	printf("%d",StdLen - (Left + Len1) - (Right + Len2) );
}
/*
abcd123ab888efghij45ef67kl,ab,ef
*/

猜你喜欢

转载自blog.csdn.net/qq_41513352/article/details/83311816
今日推荐