KMP算法:LeetCode 28

对于出现,在一个串中查找是否出现过另一个串,这是KMP的看家本领。

kmp的口诀基本就是将问题分为两步:

第一步:解决next数组的建立;

第二步:解决在匹配串中的定位问题。

先看看Strstr(),这道力扣第28题的具体解题的答案

第一步:构建next数组

1:

我习惯于直接通过将next表与前后缀最大相等长度值联系,便于我自己理解

首先第一步应该是初始化

1、将前缀末尾 j 定位在0号位置;

2、将第一个位置的next保存值置为0.

2:

因为 i 是后缀的末尾,他是完成整个模式串匹配的信号,我们需要以他为循环条件构建循环

同时要注意,i 为从1开始,而非0,因为我们已经在初始化的时候将next的0号位初始为0了。

for(int i = 1; i < s.size(); i++) {

3:

前缀后缀在末尾不相同的情况下的 寻找上一位的next保存值,同时要记住这个不相同的条件继续满足的话还需要继续寻找上一位的next保存值,因此这里必须要使用while循环,我们还得考虑 j > 0以防止出界。

while (j > 0 && s[i] != s[j]) {

j = next[j - 1];}

4:

前缀后缀经过上面的不相同的”调教“后,就考虑相等的情况了,这个顺序不能改变,一定是先考虑不相等,再考虑相等的。相等时我们将 j 向后移位,等等第二步循环中的i++会帮我们去看有没有往后的前后缀中有没有相等的情况:

if (s[i] == s[j]) {

j++;}

5:

完成了上面的顺序结构后,更新我们的对于匹配串中 i 位置的next保存值。最后在一次次循环中构建好我们的next数组。

第一步:使用next数组

其实内容真的和搭建next数组超级像!

1:

先调用函数获取我们构建好的next数组并初始化,此时 i, j 代表的含义就next数组中的含义不太一样了

i 代表的是匹配串中的指针,而 j 代表的是模式串中的指针。

int next[needle.size()];getNext(next, needle);

2:

搭建外循环,此时 i 应该从0开始,一直遍历到每个匹配串的字符中去

for (int i = 0; i < haystack.size(); i++) {

3:

与next数组类似,此时也是先考虑不匹配的情况下,然后循环的去寻找到匹配,但是这里的匹配就要注意了,他是匹配串中的当前字符与模式串中的当前字符是否匹配,同样也是while循环

while(j > 0 && haystack[i] != needle[j]) { j = next[j - 1];}

4:

考虑相匹配的情况,j++

if (haystack[i] == needle[j]) { j++;}

5:最后看看是不是全部匹配到了,因为这里前面有在最后一个匹配成功的情况下有 j++,因此此时 j 代表的含义就是模式串的长度

if (j == needle.size() ) {return (i - needle.size() + 1);}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值