KMP模版

#include<iostream>
using namespace std;
#pragma warning(disable : 4996)
const int MAXN = 1000;
int Next[MAXN];

void get_next(char *pat, int length)
{
	int i = 0, j = -1;
	Next[0] = -1;
	while(i < length)
	{
		if(j == -1 || pat[i] == pat[j])
		{
			i++;
			j++;
			Next[i] = j;
		}
		else
		{
			j = Next[j];
		}
	}
}
int kmp(char *text, char *pat)
{
	int lent = strlen(text);
	int lenp = strlen(pat);
	get_next(pat, lenp);
	int i = 0, j = 0;
	while(i < lent && j < lenp)
	{
		if(j == -1 || text[i] == pat[j])
		{
			i++;
			j++;
		}
		else
		{
			j = Next[j];
		}
	}
	if(j >= lenp)
	{
		return i - lenp;
	}
	else
	{
		return -1;
	}
}

int main()
{
	char text[MAXN] = {0};
	char pat[MAXN] = {0};
	scanf("%s%s", text, pat);
	printf("%d\n", kmp(text, pat));
	/*for(int i = 0; i <= strlen(pat); i++)
	{
		cout << Next[i] << endl;
	}*/
	return 0;
}

next数组的理解:

不为自身的最长首尾重复子串的长度。

必须满足不以text[i]结尾的j个字符与pat串的前j个字符匹配


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#pragma warning(disable : 4996)
int n, m;
char text[1000], pat[1000];
int Next[1000];
void get_next()
{
	Next[1] = 0;
	int i, j = 0;
	for(i = 2; i <= m; i++)
	{
		while(j > 0 && pat[j+1] != pat[i])
		{
			j = Next[j];
		}
		if(pat[j+1] == pat[i])
		{
			j += 1;
		}
		Next[i] = j;
	}
}
int kmp()
{
	get_next();
	int i, j = 0, cnt = 0;
	for(i = 1; i <= n; i++)
	{
		while(j > 0 && pat[j+1] != text[i])
		{
			j = Next[j];
		}
		if(pat[j+1] == text[i])
		{
			j += 1;
		}
		if(j == m)
		{
			cnt++;
			j = Next[j];
		}
	}
	return cnt;
}
int main()
{
	while(scanf("%s%s", text+1,pat+1) != EOF)
	{
		m = strlen(pat+1);
		n = strlen(text+1);
		kmp();
		printf("%d\n", kmp());

	}
}

//cnt输出text串中含有多少pat子串

next数组的理解:

以自身结束的最长首尾重复子串的长度。

必须满足以text[i]结尾的j个字符与pat串的前j个字符匹配



-----------------------

KMP匹配的实质:
A[i-j+1..i]与B[1..j]的匹配
B[1..P[j]]与B[j-P[j]+1..j]的匹配

posted @ 2013-05-05 17:35  N3verL4nd  阅读(125)  评论(0编辑  收藏  举报