终于弄懂KMP算法了

1.简例弄懂KMP-点此链接查看

看了上面的文章,你肯定大概明白了KMP的运作原理,但是你可能对于文章提到的“部分匹配值”的又来还存在疑惑,那么请继续往下看:

我们先抛出两个问题,当目标字符串i指针与模式字符串j指针失配时:
1、当母串和模式串不匹配时,i指针为什么不需要回溯?
2、当母串和模式串不匹配时,i指针不回溯,那么j指针应该移动到哪?
通过解释第1个问题,我来引出第2个问题。(其实第1个问题,你不明白,不影响你研究第2个问题,你也可以理解了第2个问题后来分析第1个问题。)
对于母串S和模式串T,如果母串的指针i处与模式串的j处失配,假设母串存在回溯i到back(i) (匹配前的i < back(i) < i),有与模式串的从0开始的模式串有一段一样长的“段落”,这个母串的段落只有是S[back(i)] 至S[i-1]才有意义,如果从S[back(i)] 至S[i-1]的过程中就已经不匹配了,那回溯至这个back(i)就更没有必要了。 即S[back(i) …i-1]=T[0…x] ,x = i-1-back(i)。又因为前面失配时存在同样长度的段落,即S[back[i]…i-1] = T[ j -1-x… j-1],所以T[0…x] = T[j-1-x …j-1]

这其实就转化成了i不变,j指针移动到x+1(后面讨论用next[j] 表示 x +1 )的问题。

看到这儿,虽然我们应该已经理解了KMP算法的运作原理,那么如何求模式传T匹配失败时的指针移动值next[j]呢:

C code--
void GetNextArrayForKMP(char *sub_str, int *next)
{
  int i = 0, j = -1, len = strlen(sub_str);
  next[0] = -1;    // printf("i = 0; j = -1; next[0] = -1 \n");
  while (i < len - 1) {
    if (j == -1 || sub_str[i] == sub_str[j]) {
      ++i;         // printf("++i = %d; ", i);
      ++j;         // printf("++j = %d; ", j);
      next[i] = j; // printf("next[%d] = %d; ", i, j);
    } else {
      j = next[j]; // printf("j = next[j] = %d ; ", j);
    }              // printf("\n");
  }
}

在kmp函数中,next使用是因为出现了失配现象:即当前模式串和主串字符不等,但是他们前面的字符都匹配。失配时模式串当前位置pj,主串的当前位置si。
失配时假设模式串不进行回溯,而调到k位置,即前面的k-1个字符和主串当前位置si的前k-1个字符匹配,然而主串的k-1字符和模式串当前位置pj的k-1位置匹配。因此模式串前k-1个字符和模式串当前位置pj的前k-1个字符匹配,即:P1…Pk-1 = Pj-k+1…Pj-1
求next的函数跟kmp函数非常类似。
求next数组时候,模式串sub_str既是主串又是模式串。
代码中i指向的是主串,j指向的是模式串,当sub_str[i] != sub_str[j]时候,说明出现了失配现象,模式串需要改变位置,j = next[j];

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
KMP算法(Knuth-Morris-Pratt算法)是一种字符串匹配算法,用于在一个文本串S中查找一个模式串P的出现位置。它的核心思想是利用已经匹配过的部分字符,尽量减少不必要的比较次数。 KMP算法的步骤是这样的: 1. 预处理模式串P,得到一个next数组。next[i]表示P[0:i]这个子串中,最长的相等前缀和后缀的长度。我们可以通过不断比较P的前缀和后缀得到这个next数组。 2. 遍历文本串S,同时遍历模式串P。当遇到不匹配的字符时,根据next数组,将模式串P向右移动尽量少的距离。移动的距离由next数组中的值决定。 3. 当P移到最右端时,如果还是没有匹配成功,则继续将P向右移动一个位置,继续匹配。 这样,通过预处理模式串P,我们能够在匹配过程中尽量少的进行字符比较,提高了算法的效率。 终于全部弄懂KMP算法,我明白了它的原理和实现过程。它的核心在于构建next数组,这个数组能够帮助我们在匹配过程中避免重复比较已经匹配过的字符。通过next数组,我们可以事先知道模式串P中的每个位置的最长相等前缀和后缀的长度,从而决定每次匹配过程中的移动距离。 KMP算法是一种高效的字符串匹配算法,它的时间复杂度为O(n+m),其中n和m分别是文本串S和模式串P的长度。相比于暴力匹配算法的时间复杂度O((n-m+1)m),KMP算法具有明显的优势。 了解KMP算法的原理和实现,对于我在日常编程中遇到的字符串匹配问题将会更加得心应手。我相信通过不断实践和总结,我能够更加熟练地运用KMP算法,解决字符串匹配相关的挑战。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值