码迷,mamicode.com
首页 > 编程语言 > 详细

算法学习-KMP(字符串匹配)解释

时间:2014-10-20 17:26:30      阅读:233      评论:0      收藏:0      [点我收藏+]

标签:算法   kmp   字符串匹配   

KMP算法

BF算法

BF算法就是我们最基本的求解字符串匹配的算法,算法的时间复杂度为O(M*N),空间复杂度为O(1),具体过程如下:

第一次 第二次 第三次 第四次
模式串S[i] abcababc abcababc abcababc abcababc
匹配串T[j] ababc ababc ababc ababc

可以看到在第三次匹配失败的时候,我们要回溯,直接S串直接i+=1,然后T串j=0从头继续开始。这样复杂度就比较高了。

KMP算法

而KMP算法就是为了解决BF算法的复杂度比较高而出现的,KMP算法的时间复杂度为O(M+N),空间复杂度为O(N),具体过程如下:

第一次 第二次 第三次 第四次
模式串S[i] abaababc abaababc abaababc abaababc
匹配串T[j] ababc ababc ababc ababc
第四次 第五次 第六次 第七次 第八次
abaababc abaababc abcababc abcababc abcababc
ababc ababc ababc ababc ababc

在第四次匹配失败后,不进行回溯,而是直接对匹配串进行下一个匹配,是因为前面已经把aba匹配过了,知道前一个也是a不需要再次进行匹配,这个就是通常所说的KMP算法。而在匹配失败后到底对哪个进行再次匹配,也就需要我们求next[j]数组了。

求next数组

next数组存放的是,当匹配失败后,需要跳转到哪个字符再次进行匹配。
求的方法,手算:
例子(ababc)的next数组为:[-1 0 0 1 2].


i = 0, j=-1, next[0]=-1, next[1]=0;


next[2] = next[1+1];
next[1] = 0
T[1] != T[0];
则next[2] = next[1] = 0;


next[3] = next[2+1];
next[2] = 0;
T[2] == T[0] (T[2] = a, T[1] = b)
则next[3] = next[2]+1;


next[4] = next[3+1];
next[3] = 1;
T[3] == T[1];
则next[4] = next[3]+1 = 2;

以上是手算的解法,代码求解比较简单。
如下

void getNextval(char *p,int *next)
{
    int j,k;
    next[0]=-1;
    j=0;
    k=-1;
    while(j<strlen(p)-1)
    {
        if(k==-1||p[j]==p[k])    //匹配的情况下,p[j]==p[k]
        {
            j++;
            k++;
            next[j]=k;
        }
        else                   //p[j]!=p[k]
            k=next[k];
    }
}


改进后的next数组

改进的之后的next数组效率更高,但是我暂时还没找到如何手算,假如你知道,请评论给我,非常感谢。但是代码实现非常简单,就是在第一次判断之后,再进行一次判断。
代码如下:

void getNext(char *str, int *next){
    int i = 0;
    int length = (int)strlen(str);
    int j = -1;
    next[0] = -1;
    while (i < length-1) {
        if (j == -1 || str[i] == str[j]) {
            ++i;
            ++j;
            if (str[i] != str[j]) {
                next[i] = j;
            }else{
                next[i] = next[j];
            }
        }else{
            j = next[j];
        }
    }
}


KMP代码实现

而KMP整个的代码实现如下:

int KMP(const char *src, const char *tar, int *next){
    int srcLength = (int)strlen(src);
    int tarLength = (int)strlen(tar);
    int i = 0, j = 0;
    while (i < srcLength && j < tarLength) {
        if (j == -1 || src[i] == tar[j]) {
            ++i;
            ++j;
        }else{
            j = next[j];
        }
    }
    if (j >= tarLength) {
        return i-tarLength;
    }else{
        return -1;
    }
}


算法学习-KMP(字符串匹配)解释

标签:算法   kmp   字符串匹配   

原文地址:http://blog.csdn.net/alps1992/article/details/40301207

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!