一、什么是 KMP 算法

KMP 算法是一种改进的字符串匹配算法,用于判断一个字符串是否是另一个字符串的子串

二、KMP 算法的时间复杂度

O(m+n)

三、Next 数组 - KMP 算法的核心

KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个 next() 实现

1、next 数组

长度与字符串长度一致,每个位置存储对应字符的最长匹配长度

2、next 数组通过遍历子字符串中"前缀"和"后缀"的最长的共有元素的长度来获得

例如 ABCDABD,得到的 next 数组为 [0,0,0,0,1,2,0]

简单地观察一下就会发现,该算法会进行最少 21 次的字符串判断,这还是在不考虑字符串匹配的时间消耗,光此一项的时间复杂度就是

O(n) = (n(n - 1)) /2 = n² / 2 + n / 2 = n²

在加上匹配字符串,就是m + n²显然大于KMP算法的时间复杂度m + n

3、next数组通过加入回溯法,在遍历子字符串时,判断逐步判断字符是否相同

function get_next(s) {
var i = 1;
var j = 0;
var next = [0];
while (i < s.length) {
if (j == 0 || s.charAt(i - 1) == s.charAt(j - 1)) {
i++;
j++;
next.push(j);
} else {
j = next[j - 1];
}
}
return next;
}

例如:

j=0,    i=1,    (j=0),     next=[0,1];
j=1, i=2, (A!=B), j=next[0];
j=0, i=2, (j=0), next=[0,1,1];
j=1, i=3, (A!=C), j=next[0];
j=0, i=3, (j=0), next=[0,1,1,1];
j=1, i=4, (A!=D), j=next[0];
j=0, i=4, (j=0), next=[0,1,1,1,1];
j=1, i=5, (A=A), next=[0,1,1,1,1,2];
j=2, i=6, (B=B), next=[0,1,1,1,1,2,3];

总共运行9次就获得了next数组,算法时间复杂度是O(n) = n

4、对于两个next数组的用法也有区别

//1.阮
//i值即移动位数:移动位数 = 已匹配的字符数 - 对应的部分匹配值
function kmp(s1, s2) {
var next = getNext(s2);
var j = 0;
for (var i = 0; i < s1.length;) {
for (; j < s2.length; j++) {
if (s1.charAt(i + j) != s2.charAt(j)) {
i += j > 0 ? (j - next[j - 1]) : 1;
j = next[j > 0 ? j - 1 : 0];
break;
} else if (j == s2.length - 1) {
return i;
}
}
}
return -1;
} //2.程
function kmp2(s1, s2) {
var j = 0;
var next = get_next(s2);
for (var i = 0; i < s1.length;) {
for (; j < s2.length; j++) {
if (s1.charAt(i) != s2.charAt(j)) {
j == 0 ? i++ : true;
j = next[j > 0 ? j - 1 : 0];
break;
} else if (j == s2.length - 1) {
return i - j;
}
i++;
}
}
return -1;
} //3.也正是由于i值的大小随着j值的大小进行改变,
// 使得被查找字符串仅被遍历一次即可得到解。
// 故时间复杂度为m
// 加上获得next数组的时间复杂度就是kmp算法的总时间复杂度m+n;

KMP算法的时间复杂度与next数组分析的更多相关文章

  1. KMP算法的next函数求解和分析过程

    转自 wang0606120221:http://blog.csdn.net/wang0606120221/article/details/7402688 假设KMP算法中的模式串为P,主串为S,那么 ...

  2. 关于KMP算法中,获取next数组算法的理解

    参考:KMP入门级别算法详解--终于解决了(next数组详解) https://blog.csdn.net/lee18254290736/article/details/77278769 在这里讨论的 ...

  3. hdu3336解读KMP算法的next数组

    查看原题 题意大致是:给你一个字符串算这里面全部前缀出现的次数和.比方字符串abab,a出现2次.ab出现2次,aba出现1次.abab出现1次.总计6次. 而且结果太大.要求对1007进行模运算. ...

  4. KMP算法解析(转自图灵社区)

    KMP算法是一个很精妙的字符串算法,个人认为这个算法十分符合编程美学:十分简洁,而又极难理解.笔者算法学的很烂,所以接触到这个算法的时候也是一头雾水,去网上看各种帖子,发现写着各种KMP算法详解的转载 ...

  5. 深入理解KMP算法之续篇

    前言: 纠结于KMP已经两天了,相较于本人之前博客中提到的几篇博文,本人感觉这篇文章更清楚地说明了KMP算法的来龙去脉. http://www.cnblogs.com/goagent/archive/ ...

  6. kmp算法简明教程

    在字符串s中寻找模式串p的位置,这是一个字符串匹配问题. 举例说明: i = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 s = a b a a c a b a a a b a a ...

  7. KMP算法的优化与详解

    文章开头,我首先抄录一些阮一峰先生关于KMP算法的一些讲解. 下面,我用自己的语言,试图写一篇比较好懂的 KMP 算法解释. 1. 首先,字符串"BBC ABCDAB ABCDABCDABD ...

  8. 利用KMP算法解决串的模式匹配问题(c++) -- 数据结构

    题目: 7-1 串的模式匹配 (30 分) 给定一个主串S(长度<=10^6)和一个模式T(长度<=10^5),要求在主串S中找出与模式T相匹配的子串,返回相匹配的子串中的第一个字符在主串 ...

  9. KMP算法字符串查找子串

    题目: 经典的KMP算法 分析: 和KMP算法对应的是BF算法,其中BF算法时间复杂度,最坏情况下可以达到O(n*m),而KMP算法的时间复杂度是O(n + m),所以,KMP算法效率高很多. 但是K ...

随机推荐

  1. Django Model 模型

    参考: https://www.runoob.com/django/django-model.html https://www.cnblogs.com/taosiyu/p/11260000.html ...

  2. springboot:非web启动

    需要运行一些调度任务,但是又不想放到web容器中运行. 见红色代码: import java.util.concurrent.ThreadPoolExecutor; import org.spring ...

  3. 关于【vue + element-ui Table的数据多选,多页选择数据回显,分页记录保存选中的数据】的优化

    之前写的[vue + element-ui Table的数据多选,多页选择数据回显,分页记录保存选中的数据]这篇博客.功能虽然实现了相对应的功能.但是用起来很不爽.所以进行了优化. 备注:最近可能没时 ...

  4. 【Linux】修改root密码

    sudo passwd root 然后提示输入两次新密码就可以了

  5. 线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式

    1. 通过Executors创建线程池的弊端 在创建线程池的时候,大部分人还是会选择使用Executors去创建. 下面是创建定长线程池(FixedThreadPool)的一个例子,严格来说,当使用如 ...

  6. 介绍一款好用的命令行工具Cmder

    一.Cmder的介绍: 在大多数情况下,我们都想复制命令行窗口中的命令行,但是cmd复制粘贴大家都懂得:有没有更好的工具替代呢? 答案是肯定的,今天我将为大家介绍一款工具--Cmder. Cmder可 ...

  7. PS 有哪些小技巧让你好用到哭?

    作者:bart链接:https://www.zhihu.com/question/328895616/answer/763462289来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...

  8. 收藏单词TOEFL备份托福英语

    TOEFL托福词汇串讲(文本) alchemy(chem-化学)n. 炼金术 chemistry 化学 alder 赤杨树 联想:older 老人坐在赤杨树下 sloth 树懒 algae n.海藻 ...

  9. centos 7 搭建 k8s

    环境 Centos 7.2 master 192.168.121.101node-1 192.168.121.134node-2 192.168.121.135 Kubernetes集群组件:– et ...

  10. left join 左边有数据,右边无数据

     参考了链接: https://blog.csdn.net/chenjianandiyi/article/details/52402011   主要是and和where的区别:   原Sql: Con ...