KMP算法

一:KMP完整代码

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

char s[101];                     //主串(0号单元未用)
char t[51];                      //模式串(0号单元未用)
int nextval[50] = { 0 };         //(0号单元未用)

//t_len表示“模式串”的长度,注意不是t字符数组的长度,因为0号单元未用
void GetNextval(int* _nextval, int & t_len)
{
	int i = 1;
	int j = 0;
	_nextval[1] = 0;

	while (i <= t_len)
	{
		if (j == 0 || t[i] == t[j])
		{
			i++;
			j++;

			if (t[i] != t[j])
				_nextval[i] = j;
			else
				_nextval[i] = _nextval[j];
		}
		else
			j = _nextval[j];
	}
}

//同样,这里的t_len和s_len不是字符串的长度,而是主串和模式串的长度,需要去掉未用的0号单元
int KMP(int* _nextval, int & s_len, int & t_len)
{
	GetNextval(_nextval, t_len);//得到next数组

	int i, j;
	i = j = 1;

	while (i <= s_len&&j <= t_len)
	{
		if (j == 0 || s[i] == t[j])
		{
			i++;
			j++;
		}
		else
			j = _nextval[j];
	}

	if (j > t_len)
		return i - t_len;//匹配成功
	else
		return 0;
}

int main()
{
	t[0] = s[0] = '#';
	int s_len, t_len;

	cout << "请输入主串: ";
	cin >> s + 1;
	s_len = strlen(s + 1);
	
	cout << "请输入模式串: ";
	cin >> t + 1;
	t_len = strlen(t + 1);

	int n = KMP(nextval, s_len, t_len);
	if (n)
		cout << "在第" << n << "位匹配成功!\n";
	else
		cout << "匹配不成功!\n";

	return 0;
}


二:测试



三:算法分析

如果文本串的长度为n,模式串的长度为m,那么匹配过程的时间复杂度为O(n),算上计算next的O(m)时间,KMP的整体时间复杂度为O(m + n)。


四:扩展

1.BM算法:

      KMP的匹配是从模式串的开头开始匹配的,而1977年,德克萨斯大学的Robert S. Boyer教授和J Strother Moore教授发明了一种新的字符串匹配算法:Boyer-Moore算法,简称BM算法。该算法从模式串的尾部开始匹配,且拥有在最坏情况下O(N)的时间复杂度。在实践中,比KMP算法的实际效能高。

2.Sunday算法

      我们已经介绍了KMP算法和BM算法,这两个算法在最坏情况下均具有线性的查找时间。但实际上,KMP算法并不比最简单的c库函数strstr()快多少,而BM算法虽然通常比KMP算法快,但BM算法也还不是现有字符串查找算法中最快的算法,本文最后再介绍一种比BM算法更快的查找算法即Sunday算法。Sunday算法由Daniel M.Sunday在1990年提出,它的思想跟BM算法很相似。上述算法请参考:http://blog.csdn.net/laojiu_/article/details/50767615







参考链接: 从头到尾彻底理解KMP----->http://blog.csdn.net/v_july_v/article/details/7041827

你可能感兴趣的:(数据结构,KMP,匹配,BM)