您的位置:首页 > 编程语言

KMP 算法实现 及代码解释

2014-11-20 00:34 337 查看
KMP算法就是在一般的比较算法的基础上增加了覆盖因子,避免了每次出现不匹配的时候再从头 开始匹配。

这里所讲匹配因子 即:使得 pattern[0]pattern[1]......pattern[k] = pattern[j-k]pattern[j-k+1]......pattern[j] 中的K。

举例说明:

pattern = abcdhjkabcd

可以看出 pattern[0]...pattern[3] = pattern[7]....pattern[10] ,所以pattern 的覆盖因子为3.

同理可得 abcdhjkabc 的 覆盖因子为2.

但是当 pattern1 = abcehjkabcd 时,其覆盖因子则为-1(假定初始值为-1,一个匹配为0,……以此计),

而abcehjkabc 的覆盖因子同样为2

覆盖因子的用法,以pattern1示例说明:

target:abcehjkabcehjkabcd

pattern:abcehjkabcd

abcehjkabcd

当红色字体匹配失败时,一般的算法会将pattern会退至字符串开头a,target前进一步,重新进行匹配。这样,效率很低。我们可以很明显的看出匹配成功的字符串中的蓝色字体是重叠的,那么我们可以跳过这部分重叠的部分再做比较,即将pattern向前移动j-overlay[j]。(注:j是匹配失败的字符的下标,overlay[j]即前j个字符的覆盖因子)。

如此便达到了快速匹配的目的。

对于计算覆盖因子可以采用递推的,可以假设pattern的前j个字符

a0a1...ak-1ak=aj-kaj-k+1...aj-1aj
则对于 pattern 的前 j+1 序列字符,则有如下可能
⑴ pattern[k+1]==pattern[j+1]  此时 overlay(j+1)=k+1=overlay(j)+1
⑵pattern[k+1]≠pattern[j+1]  此时只能在 pattern 前 k+1 个子符组所的子串中找到相应的overlay 函数,h=overlay(k),如果此时 pattern[h+1]==pattern[j+1],则 overlay(j+1)=h+1 否则重复(2)过程


上代码(调试通过):

#include "stdAfx.h"
#include <iostream>
#include <vector>
#include <string.h>
#include <stdio.h>
using namespace std;

int kmp_find(const string target,const string pattern)
{
int patlength = pattern.size();
int tarlength = target.size();
int* overlay_value = new int[patlength];
int indx;
// 计算覆盖因子
overlay_value[0] = -1;
for (int i=1;i<patlength ;i++)
{
indx = overlay_value[i-1];
while (indx >= 0 && (pattern[i]!= pattern[indx+1]))
indx = overlay_value[indx];
if(pattern[i]== pattern[indx+1])
overlay_value[i] = indx +1;<span style="white-space:pre">	</span>
else
overlay_value[i] = -1;
}

int tarIndx = 0;
int patIndx = 0;
 
//
while((tarIndx < tarlength) && (patIndx < patlength ))
{
if(target[tarIndx] == pattern[patIndx])
{
++tarIndx;
++patIndx;
}
else if (patIndx == 0) //避免出现下表为-1的情况
{
++tarIndx;
}
else
{
patIndx = overlay_value[patIndx-1]+1;
}

}
if(patIndx == patlength)
return 1;
return -1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: