C++ KMP_前缀表(next)计算解析

KMP用于判断模式串sub_str与目标串str的匹配。

简单来说可以分为两步,首先得到sub_str的next数组(数组大小与sub_str相同)。第二步利用next数组进行匹配。

难度在于理解next数组每个数代表什么以及根据sub_str求解next数组。

那next数组内的每一个数表示什么意思呢?

答:每个数next[i]表示 从sub_str[0]到sub_str[i]的子串的最长相等前后缀的长度。

前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串

后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串

用一个例子解释如何得到子串的所有前缀、后缀,并根据前缀集合和后缀集合得到最长相等前后缀的长度:

假设sub_str为iioiikiio。

next[0]: 0-0

其对应的子串为i,根据前缀和后缀的定义,前缀集合为空集合,后缀集合为空集合。

因此最长相等前后缀的长度为0,也意味着next[0]为0。

next[4]:0-4

其对应的子串为iioii,根据前缀和后缀的定义,前缀集合为[i,ii,iio,iioi],后缀集合为[ioii,oii,ii,i]。

可以看到前缀集合和后缀集合的最长相同元素为ii,因此最长相等前后缀的长度为2,也意味着next[i]为2。

根据上面的思路,最终可以得到next数组。

代码求解:

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main(){
    string s;
    cin>> s;
    int next[s.size()];
    int j =0;
    next[0] =0;   #初始化next数组
    for(int i=1;i<s.size();i++){
        while(s[i]!=s[j]&&j>0){
             j = next[j-1]; //j指向与当前字符比较的字符下标
        }
        if(s[i]==s[j]){
            j++;
        }
        next[i] =j; //后面四行代码表示,从while循环出来之后,j只有两种情况,要么找到了s[i]==s[j]且就j!=0,要么j==0。前一种情况表示当前next[i] = j +1。后一种next[i]=0,表示下一次需要从头比较。
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值