在计算机科学中,Knuth-Morris-Pratt字符串查找算法(简称为KMP算法)可在一个主文本字符串S内查找一个词W的出现位置。此算法通过运用对这个词在不匹配时本身就包含足够的信息来确定下一个匹配将在哪里开始的发现,从而避免重新检查先前匹配的字符。
这个算法是由高德纳和沃恩·普拉特在1974年构思,同年詹姆斯·H·莫里斯也独立地设计出该算法,最终由三人于1977年联合发表。
#include<iostream>
#include<string>
using namespace std;
int* buildNext(string P)
{
//构造模式串P的next表
size_t m = P.length(), j = 0;//主串指针
int* N = new int[m];//next表
int t = N[0] = -1;//模式串指针
while (j<m-1)
{
if (0 > t || P[j] == P[t])
{
//匹配
j++;
t++;
N[j] = t;//此句可改进
}
else
{
//失配
t = N[t];
}
}
return N;
}
//如果匹配成功那么返回值是模式串在文本串中的起始位置,反之
int match(string P, string T)
{
//KMP算法
int* next = buildNext(P);//构造next表
int n = (int)T.length(), i = 0;//文本串指针
int m = (int)P.length(), j = 0;//模式串指针
while (j < m && i < n)
{
//自左向右逐个比对字符
if (0 > j || T[i] == P[j])//若匹配,或者P已经移出最左侧(两个判断的次序不可交换)
{
i++;
j++;//则转到下一字符
}
else
{
//否则
j = next[j];//模式串右移,文本串不用回退
}
}
delete[]next;//释放next表
return i - j;
}
int main()
{
string pattern = "123456789";
string text = "1234567890abcdefghijklmnopqrstuvwxyz";
cout << match(pattern, text);
getchar();
return 0;
}