数据结构(串之KMP算法)

若不经常出现子串与模式串部分匹配的问题,KMP算法和朴素算法差不多

KMP算法:主串不回溯,只有模式串的指针回溯

求next数组

当模式串的第 j 个字符匹配失败时,令模式串跳到 next[j],再继续匹配

串的前缀:包含第一个字符且不包括最后一个字符的子串

串的后缀:包含最后一个字符且不包括第一个字符的子串

当第j个字符串匹配失败,由前1~j-1个字符组成的串记为S,则:

next[j] = S的最长相等前后缀长度+1

注:next[1] = 0

模式串:ababaa
序号J 1 2 3 4 5 6
模式串 a b a b a a
next[j] 0 1 1 2 3 4
模式串:aaaab
序号J 1 2 3 4 5
模式串 a a a a b
next[j] 0 1 2 3 4

KMP算法实现

//S为原串,T为模式串,next是构造的数组
int Index_KMP(SString S,SString T,int next[])
{
     
    int i=1,j=1;
    while(i<=S.length && j<=T.length)
    {
     
        if(j==0 || S.ch[i]==T.ch[i])
        {
     
            ++i;
            ++j;
        }
        else
            j = next[j];
    }
    if(j>T.length)
        return i-T.length;
    else
        return 0;
}

//next[]不作为参数传进来
//平均时间复杂度O(m+n)
int Index_KMP(SString S,SString T)
{
     
    int i=1,j=1;
    int next[T.length+1];
    get_next(T,next);//时间复杂度O(m),m为模式串长度
    while(i<=S.length && j<=T.length)
    {
     
        if(j==0 || S.ch[i]==T.ch[j])
        {
     
            ++i;
            ++j;
        }
        else
            j=next[j];
    }
    if(j>T.length)
        return i-T.length;
    else
        return 0;
}

优化next数组——>nextval

解决无意义对比

模式串:google
序号 1 2 3 4 5 6
模式串 g o o g l e
next[j] 0 1 1 1 2 1
nextval[j] 0 1 1 0 2 1
模式串:aaaab
序号 1 2 3 4 5
模式串 a a a a b
next[j] 0 1 2 3 4
nextval[j] 0 0 0 0 4
模式串:ababaa
序号 1 2 3 4 5 6
模式串 a b a b a a
next[j] 0 1 1 2 3 4
nextval[j] 0 1 0 1 0 4

我的博客 www.aiguitar.top

你可能感兴趣的:(数据结构,数据结构,字符串)