上学期上数据结构的时候就学了这个算法,可是没好好听(摊手)。这次刷题的时候遇到了一个字符串匹配题,于是学会了这个算法。
看了这么多博客,觉得对原理讲得比较好的就是这篇:戳这里。
如果想理解,重点还是前后缀的概念。还有中间怎么跳的,这个自己写两个字符串,模拟一下就行。
下面的代码写得非常好,对理解很有帮助。为了帮助理解,加入了一些输出。
#include <iostream>
#include <stdio.h>
#define MAX_SIZE 1024
#define ElemType char
using namespace std;
void CptPfFunc( ElemType Pattern[], int PrefixFunc[] )
{
register int iLen = 0; // Length of Pattern[]
while( '\0' != Pattern[iLen] )
iLen++;
int LOLP = 0; // Lenth of longest prefix
PrefixFunc[1] = 0;
for( int NOCM=2; NOCM<iLen+1; NOCM++ ) // NOCM represent the number of characters matched
{
while( LOLP>0 && (Pattern[LOLP] != Pattern[NOCM-1]) )
LOLP = PrefixFunc[LOLP];
if( Pattern[LOLP] == Pattern[NOCM-1] )
LOLP++;
PrefixFunc[NOCM] = LOLP;
printf("%d ",PrefixFunc[NOCM]);
}
printf("\n");
}
void KMPstrMatching(char Target[], char Pattern[])
{
int PrefixFunc[MAX_SIZE];
register int TarLen = 0;
register int PatLen = 0;
// Compute the length of array Target and Pattern
while( '\0' != Target[TarLen] )
TarLen++;
while( '\0' != Pattern[PatLen] )
PatLen++;
// Compute the prefix function of Pattern
CptPfFunc(Pattern, PrefixFunc);
int NOCM = 0; // Number of characters matched
for( int i=0; i<TarLen; i++ )
{
while( NOCM>0 && Pattern[NOCM] != Target[i] )
NOCM = PrefixFunc[NOCM];
if( Pattern[NOCM] == Target[i] )
NOCM++;
if( NOCM == PatLen )
{
cout<<"KMP String Matching,pattern occurs with shift "<<i - PatLen + 1<<endl;
NOCM = PrefixFunc[NOCM];
}
}
}
int main(){
KMPstrMatching("ABCVDFAB","AB");
}