对于暴力搜索法,当搜索词对应的字符与字符串中的字符不匹配时。将搜索词整个后移一位,再从头逐个比较。这样做虽然可行,但是效率很差,因为你要把”搜索位置”移到已经比较过的位置,重比一遍。
应用KMP算法之后,则有:
“部分匹配值”就是”前缀”和”后缀”的最长的共有元素的长度。
KMP算法实现代码如下:
void prefixFun(char *pattern, int *preFun)
{
int len = 0; //length of pattern
while ('\0' != pattern[len])
len++;
int LOLP = 0; //length of longest prefix
preFun[1] = 0;
for (int NOCM = 2; NOCM <= len; NOCM++) //NOCM : number of characters matched
{
while (LOLP > 0 && pattern[LOLP] != pattern[NOCM-1])
LOLP = preFun[LOLP];
if (pattern[LOLP] == pattern[NOCM-1])
LOLP++;
preFun[NOCM] = LOLP;
}
}
void KMPstrMatching(char *target, char *pattern)
{
int tarLen = 0;
int patLen = 0;
while ('\0' != target[tarLen])
tarLen++;
while ('\0' != pattern[patLen])
patLen++;
int *preFun = new int[patLen+1];
prefixFun(pattern, preFun);
int NOCM = 0; // number of characters matched
for (int i = 0; i < tarLen; i++)
{
while (NOCM > 0 && pattern[NOCM] != target[i])
NOCM = preFun[NOCM];
if (pattern[NOCM] == target[i])
NOCM++;
if (NOCM == patLen)
{
cout<<"Pattern occurs with shift "<<i - patLen + 1<<endl;
NOCM = preFun[NOCM];
}
}
delete [] preFun;
}