kmp算法中next和nextval计算方法和代码总结

此篇文章总结的 基于kmp中的模式串方式

关于next图解如下

举例:字符串 “ababaa”

索引012345
字符ababaa
next001123

 

 

 

 

next定义写法

从索引1位置开始计算,除去第i位置,从0到 i-1,前后缀中最长重复字符长度

备注如果没有前后缀元素只要自己默认为0,如果没有相同元素默认为1

next[0]=0 默认0

next[1] =0 从1位置开始计算 默认为0

next[2] = 1,此时ab, 前后缀中没有公有为1

next[3] = 1,此时aba, 字符串前缀组合a,ab 字符串后缀组合 b,ba;前后公有最长a,所以为1

next[4] = 2,此时abab, 字符串前缀组合a,ab,aba, 字符串后缀组合 b,ab,bab;前后公有最长ab,所以为2

next[5] = 3,此时ababa, 字符串前缀组合a,ab,aba, 字符串后缀组合 b,ab,aba;前后公有最长aba,所以为3

求解代码如下:

/*
*@author: 赵秋然
*@date:2021年1月19日
*@description:kmp中next求解
*/
void kmp_next(char patt[], int next[])
{
    int i = 0, j = 1, n = strlen(patt);

    next[i] = next[j] = 0;
    while (j < n)
    {
        if (i == 0 || patt[i] == patt[j])
        {
            ++i;
            next[j + 1] = i;
            ++j;
        }
        else
        {
            i = next[i];
        }

    }
}

nextval求解方法

nextval是在next方式上的升级改进,使得模式串回退跟快速有效,减少next中不必要的比较

索引012345
字符ababaa
next001123
nextval001013

 

 

 

 

 

计算方式 

默认前2位为0

nextval计算方式需要根据next结果

索引2时,元素a,next值为1,索引为1,元素b, a≠b ;nextval[2] = next[2]=1

索引3时,元素b,next值为1,索引为1,元素b, b=b ;nextval[3] = next[1] = 0

索引4时,元素a,next值为2,索引为2,元素a, a=a ;nextval[4] = next[2] = 1

索引5时,元素a,next值为3,索引为3,元素b, a≠b ;nextval[5] = next[5] = 3

根据以上结论得出:

当前索引与next索引值相同,此时索引值为next索引值

如果不同,此时索引值为next值

/*
*@author: 赵秋然
*@date:2021年1月21日
*@description:kmp中nextval求解
*/

void kmp_nextval(char patt[], int next[])
{
    int i = 0, j = 1, n = strlen(patt);
    next[i] = next[j] = 0;

    while(j < n)
    {
        if(i == 0 || patt[i] == patt[j])
        {
              if(patt[j+1] == patt[i+1])
              {
                 next[j+1] = next[i+1];
              }
              else
                {
                    next[j+1] = i+1;
              }

              ++i;
              ++j;
        }
        else
        {
            i = next[i];
        }
    }
}

为什么会引入nextval呢?

举例:

索引012345
字符aaaaab
next001234
nextval000004

 

 

 

 

 

模式串aaaaab,构建next数组后,对字符进行匹配时,如果发现字符不匹配那么next就需要回退

如果此时是索引4位置不匹配,那么根据next值就需要回退到3,2,1的不断回退,匹配速度变慢,效率下降

nextval方式直接回退到首位置,减少了不必要的回退

 

  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值