KMP算法

来源:互联网 发布:牛股王软件下载ios 编辑:程序博客网 时间:2024/06/06 19:50

串匹配

先来回忆一下串匹配场景,不外乎是给定两个字符串 S 和 T ,然后在 S 串中查找 T 串,如果查找成功就是匹配,否则就是不匹配。比如:

S = "abababaababacb";T = “ababacb”; C = “abcc” ;那么结果就是 T 匹配 S ,而 C 不能匹配 S 。

朴素的串匹配算法

再来回顾一下朴素的匹配思想,从 S[i] 开始,逐个检查 S[i+pos] 是否与 T[pos] 相等,如果 S[i+pos] = T[pos],那么 pos++ ;如果 S[i+pos] != T[pos] ,那么 T 就要回退到 T[0] ,然后再从 S[i+1] 开始尝试匹配 T ,这就是下面的伪代码。

for(int i = 0; i < Len[S]; i++){int j;for(j = 0; j < Len[T]); j++){if(S[i+j] != T[j]) break;}if(j == Len[T])find T in S}

上面算法的问题就在于,如果出现了不匹配的情况, T 就要回退到 T[0] ,算法复杂度为 O(len[S]*len[T]) 需要从头再来吗?

//KMP算法int KMP(const char *s,const char *t,int p[]){    int len1 = strlen(s);    int len2 = strlen(t);    int i,j=0;    for(i=0;i<len1;i++)    {        //先头部队先去check一下是否相等,如果不相等则立即回溯,然后继续比较,一直回溯到合适的位置        while(j > 0 && s[i] != t[j])        {            //转换成另一个问题就是p数组怎么求?            j = p[j];        }        if(s[i] == t[j])        {            j++;        }        if(j == len2)        {            printf("Find!\n");            return 1;        }    }    printf("Not find!\n");    return 0;}
初始化数组P[7]:

P[i]表示B串的前i个字符中, 前P[i]个字符和后P[i]个字符相同 

比如:

char b[] = "ababacb"; 

p[0]=0 //这个不用,必定为0

p[1]=0

P[2]=0, 因为字符串b[]的前2个字符"ab"不符合条件. 

P[3]=1, 因为字符串b[]的前3个字符"aba",其第一个字符和最后一个字符相同

P[4]=2, 因为字符串b[]的前4个字符"abab",其前两个字符和后两个字符相同

P[5]=3, 因为字符串b[]的前5个字符"ababa",其前3个字符和后3个字符相同,都是aba

P[6]=0