KMP算法的时间复杂度与next数组分析
一、什么是 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数组分析的更多相关文章
- KMP算法的next函数求解和分析过程
转自 wang0606120221:http://blog.csdn.net/wang0606120221/article/details/7402688 假设KMP算法中的模式串为P,主串为S,那么 ...
- 关于KMP算法中,获取next数组算法的理解
参考:KMP入门级别算法详解--终于解决了(next数组详解) https://blog.csdn.net/lee18254290736/article/details/77278769 在这里讨论的 ...
- hdu3336解读KMP算法的next数组
查看原题 题意大致是:给你一个字符串算这里面全部前缀出现的次数和.比方字符串abab,a出现2次.ab出现2次,aba出现1次.abab出现1次.总计6次. 而且结果太大.要求对1007进行模运算. ...
- KMP算法解析(转自图灵社区)
KMP算法是一个很精妙的字符串算法,个人认为这个算法十分符合编程美学:十分简洁,而又极难理解.笔者算法学的很烂,所以接触到这个算法的时候也是一头雾水,去网上看各种帖子,发现写着各种KMP算法详解的转载 ...
- 深入理解KMP算法之续篇
前言: 纠结于KMP已经两天了,相较于本人之前博客中提到的几篇博文,本人感觉这篇文章更清楚地说明了KMP算法的来龙去脉. http://www.cnblogs.com/goagent/archive/ ...
- 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 ...
- KMP算法的优化与详解
文章开头,我首先抄录一些阮一峰先生关于KMP算法的一些讲解. 下面,我用自己的语言,试图写一篇比较好懂的 KMP 算法解释. 1. 首先,字符串"BBC ABCDAB ABCDABCDABD ...
- 利用KMP算法解决串的模式匹配问题(c++) -- 数据结构
题目: 7-1 串的模式匹配 (30 分) 给定一个主串S(长度<=10^6)和一个模式T(长度<=10^5),要求在主串S中找出与模式T相匹配的子串,返回相匹配的子串中的第一个字符在主串 ...
- KMP算法字符串查找子串
题目: 经典的KMP算法 分析: 和KMP算法对应的是BF算法,其中BF算法时间复杂度,最坏情况下可以达到O(n*m),而KMP算法的时间复杂度是O(n + m),所以,KMP算法效率高很多. 但是K ...
随机推荐
- 🐯 php项目中类的自动加载
主要函数:spl_autoload_register() — 注册给定的函数作为 __autoload() 的实现 将函数注册到SPL __autoload函数队列中.如果该队列中的函数尚未激活,则激 ...
- cordova调用第三方应用
cordova 帮助webapp 达到调用原生系统的功能 项目需求:在项目中调用系统中含有的第三方地图应用 需求其实分为两步: 1. 查找本地地图应用 2.成功调起本地应用 首先需要安装两个插件,安装 ...
- Spring Cloud 微服务技术整合
微服务架构风格是一种使用一套小服务来开发单个应用的方式途径,每个服务运行在自己的进程中,并使用轻量级机制通信,通常是HTTP API,这些服务基于业务能力构建,并能够通过自动化部署机制来独立部署,这些 ...
- python/shell代码片段
查看某模块路径 Bash pip show --files selenium 文件编码转换 Bash convmv -f GBK -t UTF-8 --notest -r ydcz_1/ 查找当前目录 ...
- Git - ignore过滤文件
Git - ignore 官网:https://git-scm.com/docs/gitignore 今天在初始化仓库的时候,考虑到如何过滤不需要的文件进入版本控制系统.所以去查阅了一番官方文档. 想 ...
- jQuery正则校验
jQuery正则校验 银行卡号 //验证银行卡号,bankno为银行卡号function luhnCheck(){ var bankno = $.trim($("#bankNoInp&quo ...
- git revert commitid
是生成一个和commitid的提交完全相反的提交.类似倒转.
- 翻书shader
//把下面的shader挂载到plane上,调节_Angle Shader "Unlit/PageTurning"{ Properties { _Color ("Colo ...
- lua【卤鹅】总结
转自:https://www.cnblogs.com/reblue520/p/10767428.html 编写一个简单的hello world程序 test.lua 如果觉得简单,可以给一个for循环 ...
- KepServerEX读写三菱PLC,车间现场测试记录,带你了解【数据采集的困境】的前世与今生
1.不了解KepServerEX 的鞋童,可以先了解一下OPC UA,OPC UA服务端.我们当前项目读写三菱PLC是自己写的类库,但我感觉调用不够方便灵活,工作之余用OPC UA方式尝试一下 2.数 ...