Fork me on GitHub
KMP字符串匹配算法笔记
网上有很多解释KMP算法的文章,A_B_C_ABC(见附件)的 这篇很详细,反复看了好几遍,总算理解了个大概,但是总觉得没那么爽快。其实,一种算法各人有各人的理解方法,找到适合自己理解的才容易记住。下面是我对 这个算法的一些理解:
int strstr(char *sub, char* str){
        int i=0;
        char *p=str, *q=sub;
        while(*(p+i)!='\0'&&*(q+i)!='\0'){
                if(*(q+i)==*(p+i))
                        i++;
                else{
                        p++;
                        i=0;
                }
        }       
        if(*(q+i)=='\0')
                return p-str;
        return -1;
}
下面说说我理解的KMP算法,与普通匹配算法不一样的是,KMP算法在子串匹配失效的时候,下一步并不是重新从子串的头部开始匹配,而是根据一下 next函数计算出下一步应该从子串的什么部位开始匹配。举个例子更容易说明
void calnext(char* P, int next[]){
    next[0] = -1;           //第一个元素的next总是-1, 因为根据(1) , 我们并找不到一个k比j=0小
    for(int i=1; i<strlen(P); i++){
        int k = next[i-1];     //因为采用递归的方法, 为了计算next[i], 先记录下next[i-1] 而且假设next[i-1]已知
        while(P[k+1]!=P[i]&&k>=0){ // 递归
            k = next[k];
        }
        if(P[k+1]==P[i])     //如果相等而结束, 则找到一对长度为k的前缀字串和后缀字串
            next[i] = k+1;       //增加了一个相同项
        else
            next[i] = -1;          //其他情况
    }
}
匹配的代码:
int find(char*T, char* pat){
    int n = strlen(pat);
    int *next = new int[n];
    calnet(pat, next);
    char *p=T, *q=pat;
    int i=0;
    while(*p!='\0'&&(*(q+i)!='\0')){
        if(*p==*(q+i)){
            p++;
            i++;
        }else{
            if(i==0)
                p++;
            else
                i = next[i-1]+1;
        }
    }
    if(*(q+i)=='\0')
        return p-T-n;
    else
        return -1;
}

posted on 2010-05-01 00:53  HackerVirus  阅读(271)  评论(0编辑  收藏  举报