KMP 算法实现 及代码解释

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 
#include 
#include 
#include 
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= 0 && (pattern[i]!= pattern[indx+1]))
			indx = overlay_value[indx];
	    if(pattern[i]== pattern[indx+1])
			overlay_value[i] = indx +1;	
		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;
}







你可能感兴趣的:(KMP 算法实现 及代码解释)