xyjzsh

KMP算法的一点理解

KMP算法是在给定的字符串中查找某一特定的字符串(我们称之为模式串(Pattern)).
时间复杂度是O(m+n):m是模式串的字符数,n是给定的目标串的长度。
在写自己见解之前,先给大家一个Martrix67大牛的关于KMP算法的一个链接
http://www.matrix67.com/blog/archives/115

我认为KMP算法的难点在于当匹配失效时,我们要将模式串的第几个字符与当前目标串的失效处进行比较。

我们用T来表示目标串,P(m)来表示有m个字符的模式串。
已知P[1...q] 与 T[s+1,s+2,....s+q]匹配。而P[q+1] 不等于T[s+q+1];
那么T[s+q+1]应该和P的哪个字符进行比较呢?

由P[1..q] = T[s+1,...s+q]对应相等,假设T[s+q+1]要和P[k+1]进行比较(我们是基于1的字符串,即第一个字符我们用1而不是0来表示它的下标。)
那么我们必须保证
P[1...k] = T[ s+q-k+1...,s+q].
因为在一定之前P[1...q] = T[s+1,...s+q];所以P[q-k+1...q] = T[s+q-k+1,...,s+q];
P[q-k+1,...,q]是P从q之前的k个字符,即P[q]的后面k字符。
P[1...k]是P的前k个字符。
所以当我们在P[q+1]和T[s+q+1]不匹配时,
我们就是找到最大的k,使得前k个字符和后k个字符相等。

代码如下:

 


long IndexOfSubString(LPCTSTR source,unsigned int start,LPCTSTR subStr)
{
    
long sourceLen = _tcslen(source);
    
long subLen = _tcslen(subStr);
    
    
long *helpArr = new long[subLen];
    memset(helpArr,
0,sizeof(long)*subLen);
    
    helpArr[
0=-1;

    
long index(0);
    
long j(-1);
    
for(index=1;index<subLen;index++)
    
{
        
while(j>0 && subStr[index] !=subStr[j+1]) j = helpArr[j];

        
if(subStr[index] == subStr[j+1])
            j
++;

        helpArr[index] 
= j;
    }


    j
=-1;
    
for(index=start;index<sourceLen;index++)
    
{
        
while(j>-1&&source[index] !=subStr[j+1]) j=helpArr[j];

        
if(source[index] == subStr[j+1])
            j
++;
        
if(j==subLen-1)
         
return index-j;
    }

    delete[] helpArr;
    
return -1;
}



posted on 2010-11-23 11:08 呆人 阅读(211) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2010年12月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

导航

统计

常用链接

留言簿(1)

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜