KMP
作者:互联网
KMP算法
解决的问题
字符串匹配问题,给定一个目标匹配串,一个模式串,在目标匹配串中查找模式串,若匹配串长度n,模式串长度m,可以将时间复杂度从 O ( n ∗ m ) O(n * m) O(n∗m)降低到 O ( n + m ) O(n + m) O(n+m)。
思想
暴力解法
枚举每一个原串,同时开始枚举模式串,一个一个匹配下去,若匹配失败,从原串下一个与模式串第一个重新开始匹配。
缺点:没利用好已经匹配的信息,当原串与模式串已经匹配了很多值时,一次匹配失败,全部从头与原串第二个进行匹配。
KMP
①匹配
就是利用好已匹配串的数据,对于匹配串每一个数都保存一个next数组,该next数组含义就是该数之前的数前缀与后缀相同的数量
例如 b c b c d f b c b
next 0 0 1 2 0 0 1 2 3
那么匹配的时候若遇到不匹配的数时,可以将 j,也就是模式串的匹配位置移到next值上,就能保证如果能匹配到的话能找到这种情况,如果next等于0了,说明无前缀等于后缀了,直接原串 位置 i 向后移一位,这种情况就是直接对原串下一位继续开始匹配。
②预处理
那么下一个问题就是如何求出next数组,暴力肯定是不行的,方法就是用匹配串来匹配自己,同样的方法,初始化第一位next[1] = 0,从第二位开始匹配,当while中第一次匹配成功时就是最长的时刻,此时 j 就是next值,若无匹配到,那么next就是0。
模版
//s1为待匹配串,s2为模式串,用s2来匹配s1
//两个串下标都是从1开始
for (int i = 2, j = 0; i <= m; i ++){ //预处理模式串
while (j && s2[i] != s2[j + 1]) j = ne[j];
if (s2[i] == s2[j + 1]) j ++;
ne[i] = j;
}
for (int i = 1, j = 0; i <= n; i ++){ //匹配
while (j && s1[i] != s2[j + 1]) j = ne[j]; //循环找到下一位匹配的或完全不匹配
if (s1[i] == s2[j + 1]) j ++; //如果当前对的上,继续下一位匹配
if (j == m){
//匹配成功
}
}
讲的有点乱,详细也可以这篇博客
https://www.cnblogs.com/SYCstudio/p/7194315.html
标签:匹配,s2,s1,原串,模式,next,KMP 来源: https://blog.csdn.net/weixin_44232130/article/details/113913757