KMP算法理解

KMP

我的理解 是一个通过预处理储存字符串自身具有的前后缀一致性质来达到快速处理“字符串匹配”“字符串重复”的问题的算法,
核心是 next 数组。

以字符串匹配为例子,简单阐述一下KMP算法相比于暴力算法的优越性。
举例问题是字符串 A 中有多少个字符串 B

abababaac 中找 ababab

假设已经处理到这种情况:
        1 2 3 4 5 6 7 8 9
A=a b a b a b a_ a c
B=      a b a b a_ b
假设是从A的第3位暴力处理到了第7位
现在要处理第8位,按照暴力算法的思路,由于第8位的字符对应不上,所以要将 B 的首位调到第4位重新去匹配
但是这其中可以优化,注意到 B 串中 ababa 的前缀 aba 和后缀 aba 相同,我可以直接把 B 串后移两位,变成如下情况继续匹配:
        1 2 3 4 5 6 7 8 9
A=a b a b a b a_ a c
B=           a b a_ b a b
这样子免去了暴力算法的又一次从头开始匹配,而如何让 B 去移动,就是KMP算法要处理的。(虽然这个例子优势不明显)

next数组

首先要明确这是对于字符串自身而言的性质

next[i] 表示的是字符串 S 的子串 S[1i] 中满足真前缀和真后缀相等的最长长度 len ,即满足S[1len]=S[ilen+1i]len 的最大值
举个例子, abababcnext[1]=0next[2]=0,next[3]=1,(a),next[4]=2,(ab),next[5]=3,(abc),next[6]=4,(abcd),next[7]=0;

求法如下:
1.next[1]next[i1]2.jj=next[j]j=03.j++next[i]=j

void prenet(string a) {//虽然string是从0开始的,但是在初始化之后可以在string类型变量s前面加个空格,实现形式是s.insert(0, " ");
  int n = strlen(a) - 1; //因为加了个空格所以多了1
  for (int i = 2, j = 0; i <= n; ++i){
      while (a[i] != a[j + 1] && j > 0) j = net[j];
      if (a[i] == a[j + 1]) ++j;
      net[i] = j;
  }
}

附上一些容易想到的拓展点:
1.nextnextnext[i]=
2.next[i]next[next[i]]next[next[next[i]]]inext[i]inext[j]=0j

posted @   ancer  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示