看了两个晚上的KMP,加上基本的“暴力匹配”

今晚看懂next[j]递归求解时,突然觉得算法真的好美妙,虽然觉悟的晚但晚胜过没有是吧!

我的博客都是应试性的学习笔记,不具备指导性,还是大神们写的好,例如July和matrix67的博客(今天还知道了matrix67的传奇)

[置顶] 从头到尾彻底理解KMP(2014年8月22日版)    

[置顶]         从头到尾彻底理解KMP(2014年8月22日版)

实习辞职了,可以全心全意看书找工作了,自由真是好!!为了我们俩以后在一起!!

什么时候努力都不晚,尽管我的路走的有些曲折,这鸡汤给自己灌得好哇!

今天菜鸟是为了明天的自己不菜鸟,扯多了……

 

KMP面对的问题:长串(文本串)是S串,短串(模式串)是P串,判断P串是否是S的一个子串,如果是找到P在S中的起始位置

S串 索引i 

P串 索引j

KMP的思想:(假设这里已了解“暴力匹配”算法)

①当p0,p1……pj-1与si-j,si-j+1,……si-1匹配,但pj!=si时,j不必回到0开始匹配

②而是分析P串本身的性质,让“j少回溯一些”,这就和next[j]数组的求值有关

③……(果然看懂和写出来不是一个段位的,图书馆要关门了,先写到这)

附上自己实现代码

#include <iostream>
#include <string>
using namespace std;
//KMP算法,分析短串P中本身的性质,寻找“前缀==后缀的最长串”,从而令索引j少往回走一些
void getNext(char *p, int next[]){
    int k=-1;
    int j=0;
    next[0]=-1;
    int pLen=strlen(p);
    while(j<pLen-1){
        if (k==-1||p[k]==p[j]){
            j++;
            k++;
            next[j]=k;
        }else
            k=next[k];//这里有点晦涩啊,但正是递归的精华所在
    }
}
int KmpSearch(char *s, char *p){
    int i=0,j=0;
    int sLen=strlen(s);
    int pLen=strlen(p);
    int *next=new int[pLen];
    getNext(p,next);
    while (i<sLen && j<pLen){
        if (j==-1 || s[i]==p[j])//这里j=-1还不理解
        {
            i++;
            j++;
        }else
            j=next[j];
    }
    delete next;
    if(j==pLen)
        return i-j;
    else
        return -1;
}

int main()
{
    char *s1="bbc abcdab abcdabcdabde";
    char *s2="abcdabd";
    cout<< KmpSearch(s1, s2) <<endl;
    return 0;
}

 

posted on 2014-09-12 21:28  zhangxh_Doris  阅读(318)  评论(0编辑  收藏  举报