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 ...
随机推荐
- 总结一些Java试题
1.方法重载和重写的区别: 重载是在同一个类中,同名不同参 重写是在不同类中,同名同参 2.抽象类的特点: 抽象方法和抽象类都要被关键词abstract修饰 抽象方法一定在抽象类中 抽象类不能new对 ...
- springboot底层原理简述
1.maven 子父依赖关系,快速整合第三方框架 2.无配置文件 省略了web.xml,spring.xml,springmvc.xml.mybatis.xml. spring3.0以上提供注解,sp ...
- SQL Server 2000~2017补丁包
最新更新 Product Version Latest Service Pack Latest GDR Update Latest Cumulative Update CU Release Date ...
- C++冒泡排序及优化
冒泡排序 1.经典冒泡排序 经典的冒泡排序为从左边开始依次判断排序,每次最终仅将一个数向后冒泡,而对于其他数的排序没有什么帮助:如果已经所有元素已经是有序的,依然执行循环. 2.优化冒泡排序 优化地方 ...
- 在js中使用for和forEach遍历数组
数组的遍历 for var arr = [1, 2, 3, 4]; for (var i = 0; i < arr.length; i++){ arr[i]; } forEach var arr ...
- PV、UV、UIP、VV、DAU、CTR指的是什么?
PV(page view) 网站浏览量,指网页的浏览次数,用户每打开一次页面就记录一次PV,多次打开则累加. UV(unique vistor) 独立访客数,指的是某一天访问某站点的人数,以cooki ...
- 或与异或 [背包DP]
也许更好的阅读体验 \(\mathcal{Description}\) 给定\(n\)和长度为\(n\)的数组\(a\) 问从\(a\)中选取任意个数使得其 异或起来的值 等于 或起来的值 的方案数 ...
- 向Spring 容器中注入对象的几种方法
1.使用@Bean 注解,用于注入第三方 jar 包到SpringIOC容器中. 2.使用 @Import({Order.class, Member.class, MyImportBeanDefini ...
- mssql server 排序 以及like语句
当我们按照某个字段排序时,通常使用order by语句,如果该字段存在null值,则会把null值的这条放到最上面, 那我们是否有办法解决呢? 答案是肯定的: ORDER BY CASE WHEN O ...
- Hadoop1.X集群完全分布式模式环境部署
Hadoop1.X集群完全分布式模式环境部署 1 Hadoop简介 Hadoop是Apache软件基金会旗下的一个开源分布式计算平台.以Hadoop分布式文件系统(HDFS,Hadoop Distri ...