加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

KMP算法

发布时间:2020-12-14 04:38:00 所属栏目:百科 来源:网络整理
导读:KMP算法解决的是字符串匹配的问题 文本串:aabaabaaf 模式串:aabaaf 判断文本串中是否存在模式串 需要用到 前缀表 : 前缀:包含首字母不包含尾字母的所有子串 后缀:包含为字母不包含首字母的所有子串 求最长相等前后缀 初始化 处理前后缀不相同的情况 处

KMP算法解决的是字符串匹配的问题

文本串:aabaabaaf

模式串:aabaaf

判断文本串中是否存在模式串

需要用到前缀表

  前缀:包含首字母不包含尾字母的所有子串

  后缀:包含为字母不包含首字母的所有子串

求最长相等前后缀

初始化

处理前后缀不相同的情况

处理前后缀相同的情况

更新next数组

i:指向后缀末尾位置

j:指向前缀末尾位置,还代表i包括i之前子串的最长相等前后缀长度

初始化:j=0;注意这个位置对j的初始化其实有好几种方式,有的人习惯于赋值-1,也就是对整个next数组进行-1操作;有的习惯于使用原next数组,我比较倾向于next原数组,这二者的差别只在于进行j回溯的时候那句逻辑。

next[0]=0;

?然后循环里对i进行初始化,循环里头,先判断后缀不相同的情况:不相同的话要对j进行回溯,回溯到前一位对应的回退位置;

如果前后缀相同,将j++,然后更新next数组。

这样就完成了next数组的构建。

然后进行匹配的时候,两个字符串用两个下标分别进行迭代,注意模式串的下标初始值跟next数组起始位置一样,习惯于初始化为0,这也是我为什么倾向于next数组初始化为0的原因;

还是先处理不匹配的情况,进行回溯;

匹配的话移动;

根据不同题目判读不同终止条件。

class Solution {
public:
    void getNext(int* next,const string& s)
    {
        int j = 0;//前缀的末尾,统一0操作,所以初始化为0
        next[0] = j;
        for(int i = 1; i < s.size(); i++)
        {
            先处理前后缀不相等的情况,如果不相等,前缀要进行回退,知道回退到相等或者到模式串开头位置,回退的下标就是当前前缀前一个位置的next数组的值
            while(j > 0 && s[i] != s[j])
            {
                j = next[j-1];
            }
            处理前后缀相同的情况,如果相同,i和j都往后移一位,j++,next[i]等于j
            if(s[i] == s[j])
            {
                j++;
            }
            next[i] = j;
        }
    }

    int strStr(string haystack,1)">string needle) {
        haystack是文本串
        needle是模式串
        KMP算法,需要构造next数组
       if(needle.size() == 0)
       {
           return ;
       }
       int next[needle.size()];
       getNext(next,needle);得到前缀表
       得到前缀表之后,需要进行匹配,用j来迭代模式串,用i来迭代文本串
       因为next数组里是从0开始的
       0; i < haystack.size(); i++先处理二者不相等的情况,如果不相等,模式串需要回退,按照next数组进行回退
           0 && haystack[i] != needle[j])
           {
               j = next[j-];
           }
           如果二者相等,继续向后判断
           if(haystack[i] == needle[j])
           {
               j++;i++在循环里头
           }
           判断是不是模式串在文本串里头的条件:迭代器j已经到了尾部
           if(j == needle.size())
           {
               return i - needle.size() + ;
           }
       }
       return -;
    }
};

?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读