对kmp算法的理解

注释

设有两个串st,在s串中找到一个与t串相等的子串。
我们通常把s称为目标串,t称为模式串。

引言

在讲kmp算法之前,先回忆一下简单的暴力匹配算法。其大概的思路为先从目标串的第一个字符开始和模式串的第一个字符相比较,若相等,则比较后续字符,否则从目标串的第二个字符开始重新比较。依此类推,如果匹配成功,输出模式串的第一个字符在目标串出现的位置。否则,匹配失败。

下面是暴力匹配算法的实现:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    char s[1000],t[1000];
    while(~scanf("%s%s",s,t))
    {
        int i = 0, j = 0;
        while(i < strlen(s) && j < strlen(t)) // 保证这两个串都没有扫描完
        {
            if(s[i] == t[j])                   //比较目标串和模式串的两个字符相同
               i++,j++;                       //比较后续的两个字符
            else                               //当前两个字符不相同
               i = i - j + 1,                     //目标串的i回退
               j = 0;                             //子串从头开始匹配
        }
            if(j >= strlen(t))                     //j越界,表示匹配成功
                cout << i-strlen(t) << endl;     //输出t在s中的位置
            else cout << "no" << endl;
    }
    return 0;
}

然后我们发现这个算法的平均时间复杂度大概是o(模式串长度*目标串长度),很容易理解,但是效率不高。所以就有人提出了kmp算法。

理解

上一篇已经大概说了对于next数组的理解,然后这里就直接开始说kmp算法了。如果对于next数组还是不理解可以去看我的上一篇文章。对于kmp算法中的next数组的理解
理解了next数组之后,发现kmp算法容易很多,大概的过程是这样的:

*int i = 0, j = 0;
  while(保证模式串和目标串都没有扫描完) 
  {
       if(两个字符串现所处的字符相等 || j == -1)                
             两个字符串同时向后续移动;      
       else                              
         目标串保持不变,
         模式串回退到next[j]的值的位置;
       if(j越界)                    
          输出t在s中的位置;
       else 
          输出“no”;* 
   }

有没有发现这个和暴力匹配算法很相似,kmp算法仅仅是在两个字符串现所处的字符不相同时,直接回退模式串到next【j】值所在的位置,而不是移动目标串。但他的平均时间复杂度仅为o(模式串长度+目标串长度)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值