一、什么是 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. [线性代数xOI/ACM]系数矩阵的QGXZ分解

    一些无关紧要的Q&A Q:你是怎么想到这个花里胡哨的算法的啊? A:前几天学习线性代数时有幸和Magolor大佬讨论到 $LU$ 分解在多解时的时间复杂度问题,于是yy出了这个奇怪(?)的算法 ...

  2. Access to XMLHttpRequest at 'http://127.0.0.1:8000/XXXXX' from origin 'http://localhost

    Django 报错,跨域请求出现问题. 在settings.py中添加 #设置可跨域范围 CORS_ALLOW_CREDENTIALS = True CORS_ORIGIN_ALLOW_ALL = T ...

  3. Java基础知识点总结(四)

    ”https://www.runoob.com/java/java-data-structures.html” 成员方法:是类中自己定义的方法. 构造方法:要和自己类中类名相同. 不论是构造函数还是成 ...

  4. 基于Keras搭建MLP

    Keras是一套基于Tensorflow.Theano及CNTK后端的高层神经网络API,可以非常友好地支持快速实验,本文从零开始介绍了如何使用Keras搭建MLP并给出两个示例. 基于Ubuntu安 ...

  5. Django框架之第六篇(模型层)--单表查询和必知必会13条、单表查询之双下划线、Django ORM常用字段和参数、关系字段

    单表查询 补充一个知识点:在models.py建表是 create_time = models.DateField() 关键字参数: 1.auto_now:每次操作数据,都会自动刷新当前操作的时间 2 ...

  6. 去除Chrome“请停用以开发者模式运行的扩展程序”提示

    将version.dll放在chrome同级目录,重启浏览器( 79.0.3945.79版本后已失效)                    

  7. golang在linux下的安装操作

  8. 全栈项目|小书架|服务器端-NodeJS+Koa2 实现评论功能

    评论功能分析 上图可以看出评论功能主要实现了:评论的发布.评论列表的展示. 在不考虑子评论以及图片评论的场景下,评论功能主要有以下两个接口: 发布评论 获取评论列表(考虑分页) 评论 Model 的建 ...

  9. python 字符串替换功能 string.replace()可以用正则表达式,更优雅

    说起来不怕人笑话,我今天才发现,python 中的字符串替换操作,也就是 string.replace() 是可以用正则表达式的. 之前,我的代码写法如下,粗笨: 自从发现了正则表达式也生效后,代码变 ...

  10. DotNet Core 2.2 MVC Razor 页面编译为 View.dll 文件的解决方法

    使用文本文件编辑器打开项目文件,找到: <PropertyGroup>     <TargetFramework>netcoreapp2.0</TargetFramewo ...