KMP算法 (字符串的匹配)】的更多相关文章

一.本文简介 本文的目的是简单明了的讲解KMP算法的思想及实现过程. 网上的文章的确有些杂乱,有的过浅,有的太深,希望本文对初学者是非常友好的. 其实KMP算法有一些改良版,这些是在理解KMP核心思想后的优化. 所以本文重点是讲解KMP算法的核心,文章最后会有涉及一些改良过程. 二.KMP算法简介 KMP算法是字符串匹配算法的一种.它以三个发明者命名,Knuth-Morris-Pratt,起头的那个K就是著名科学家Donald Knuth. 三.KMP算法行走过程 首先我们先定义两个字符串作为示…
KMP算法 Knuth–Morris–Pratt algorithm 克努斯-莫里斯-普拉特 算法 algorithm kmp_search: input: an array of characters, S (the text to be searched) an array of characters, W (the word sought) output: an array of integers, P (positions in S at which W is found) an int…
题目: 经典的KMP算法 分析: 和KMP算法对应的是BF算法,其中BF算法时间复杂度,最坏情况下可以达到O(n*m),而KMP算法的时间复杂度是O(n + m),所以,KMP算法效率高很多. 但是KMP算法不太好理解,其中牵涉到next数组,目标就是让模式串尽可能的往右滑动,减少比较次数,比如 a  b  a  b  c -1 0  0  1  2 比如我们比较ababc时,如果c比较发现错误,前面的abab已经比较成功,那么下次比较,我们只需要从aba的最后一个a开始比较,这样省去了从头开始…
想不到时隔两年回来重新学习KMP算法还是那么难,不过理解了大概,把例程贴上来,如果是求数量只需要加个count变量记录即可. #include"stdio.h" #include"string.h" void makeNext(const char P[],int next[]) { int q,k; int m=strlen(P); next[]=; ,k=;q<m;q++) { &&P[q]!=P[k]) k=next[k-]; if(P[…
public static int[] kmpTable(char[] seq) { int[] tbl = new int[seq.length]; tbl[0] = 1; for (int i = 1; i < seq.length; i++) {// 子串最开始 int j = tbl[i - 1];// 从已经算出的索引开始 l1: for (; j <= i; j++) { for (int k = 0; j + k <= i; k++) { if (seq[j + k] ==…
之前说到,朴素的匹配,每趟比较,都要回溯主串的指针,费事.则 KMP 就是对朴素匹配的一种改进.正好复习一下. KMP 算法其改进思想在于: 每当一趟匹配过程中出现字符比较不相等时,不需要回溯主串的 i指针,而是利用已经得到的“部分匹配”的结果将模式子串向右“滑动”尽可能远的一段距离后,继续进行比较.如果 ok,那么主串的指示指针不回溯!算法的时间复杂度只和子串有关!很好. KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的,很自然的,需要一个函数来存储匹…
基于KMP算法的字符匹配问题 反正整个清明都在纠结这玩意...差点我以为下个清明要给自己过了. 至于大体的理解,我就不再多说了(还要画图多麻烦鸭),我参考了以下两个博客,写的真的不错,我放了超链接,点击就可以传送过去了. (原创)详解KMP算法(点击跳转):图画的很棒,很好理解,一步步带你深入 KMP算法最浅显理解--一看就明白(点击跳转):对主要的疑问有很细致地回答 需要注意的是,两篇博客都是以字符数组下标为0处开始存储 我对next数组不是很理解,说是next[j]表示的是j下一个指向的模式…
1.顺序串 实现的操作有: 构造串 判断空串 返回串的长度 返回位序号为i的字符 将串的长度扩充为newCapacity 返回从begin到end-1的子串 在第i个字符之前插入字串str 删除子串 在实现返回位序号从begin到end-1的子串时,注意,此处串的起始位置为0,同时为了方便,我们再次没有新建一个变量,而是返回一个string,可以直接输出,在main函数中可以看到. 通过string.indexof()函数将字符数组转化为字符串. 同时在实现每个字符串的操作之前,先进行异常处理,…
目的: 为了解决字符串模式匹配 历程: 朴素模式匹配:逐次进行比较 KMP算法:利用匹配失败得到的信息,来最大限度的移动模式串,以此来减少比较次数提高性能 概念: m:是目标串长度 n:是模式串长度 j:某次匹配时,第一次出现的不同的索引位置(有的称为:失配位) k:最长首尾串长度(有的称为:最长公共前后缀) 核心思想: S   S0 S1 ...... Si-j-1 Si-j Si-j+1 Si-j+2 ...... Si-2 Si-1 Si ...... Sn-1 ||     ||    …
2384: [Ceoi2011]Match 1892: Match 1461: 字符串的匹配 题目大意: 数据范围: 题解: 很巧妙的一道题呀. 需要对$KMP$算法有很深的理解才行. 首先我们需要发现,要求的这个东西跟字符串匹配有点像. 我们在单个模式串匹配的时候用到的$KMP$算法,合法匹配条件是两个字符完全相同. 但是这个题本质上就是要求子串离散化之后相同. 如果两个串离散化之后完全相同,等价于一个条件,就是每个数前面比它小的个数通通相等. 这是显然的. 所以我们尝试改变$KMP$的匹配模…
1. KMP 算法(字符串匹配算法)较 BF(朴素的字符串匹配)算法有哪些改进 1) 在主串和子串匹配的过程中,主串不再回退,只改变子串的比较位置. 2) 为子串生成对应的next数组,每次匹配失败,通过访问next数组获知子串再一次开始匹配的位置. 2.  在KMP算法中,为了确定在匹配不成功时,下次匹配时j的位置,引入了next[]数组,next[j]的值表示P[0...j-1]中最长后缀的长度等于相同字符序列的 前缀. 因此KMP算法的思想就是:在匹配过程称,若发生不匹配的情况,如果nex…
一.串 串是由零个或多个字符串组成的有限序列 (一).串的定义 定长顺序存储 特点:每个串变量分配一个固定长度的存储区,即定长数组 定义: #define MAXLEN 255 typedef struct{ char ch[MAXLEN]; int length; }SString; 堆分配存储表示 这里的堆是指c语言中存在一个称之为"堆"的自由存储区,这里的堆是一个链表的结构,和数据结构中的堆是不同的! 特定:存储空间在程序执行过程中动态分配 定义 typedef struct{…
前言 算法是什么?算法就是数学规律.怎么去总结和发现这个规律,就是理解算法的过程. KMP算法的本质是穷举法,而并不是去创造新的匹配逻辑. 以下将搜寻的字符串称为子串(part),以P表示.被搜寻的字符串称为总串(total),以T表示. start代表P串在T串中开始匹配的位置,end代表P串与T串对比字符时的位置 String total = "ababcd"; String part = "abc"; total.contains(part); 部分匹配表 部…
具体参见: KMP算法详解 背景: KMP算法之所以叫做KMP算法是因为这个算法是由三个人共同提出来的,就取三个人名字的首字母作为该算法的名字.其实KMP算法与BF算法的区别就在于KMP算法巧妙的消除了指针i的回溯问题,只需确定下次匹配j的位置即可,使得问题的复杂度由O(mn)下降到O(m+n). KMP算法的思想就是:在匹配过程称,若发生不匹配的情况,如果next[j]>=0,则目标串的指针i不变,将模式串的指针j移动到next[j]的位置继续进行匹配:若next[j]=-1,则将i右移1位,…
字符串匹配是字符串的一种基本操作:给定一个长度为 M 的文本和一个长度为 N 的模式串,在文本中找到一个和该模式相符的子字符串,并返回该字字符串在文本中的位置. KMP 算法,全称是 Knuth-Morris-Pratt 算法,以三个发明者命名,开头的那个K就是著名科学家 Donald Knuth .KMP 算法的关键是求 next 数组.next 数组的长度为模式串的长度.next 数组中每个值代表模式串中当前字符前面的字符串中,有多大长度的相同前缀后缀. Boyer-Moore 算法在实际应…
视频参考 对于正常的字符串模式匹配,主串长度为m,子串为n,时间复杂度会到达O(m*n),而如果用KMP算法,复杂度将会减少线型时间O(m+n). 设主串为ptr="ababaaababaa";,要比较的子串为a=“aab”: KMP算法用到了next数组,然后利用next数组的值来提高匹配速度,我首先讲一下next数组怎么求,之后再讲匹配方式. next数组详解 首先是理解KMP算法的第一个难关是next数组每个值的确定,这个问题困恼我很长时间,尤其是对照着代码一行一行分析,很容易把…
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法数据结构专题的第29篇文章,我们来聊一个新的字符串匹配算法--KMP. KMP这个名字不是视频播放器,更不是看毛片,它其实是由Knuth.Morris.Pratt这三个大牛名字的合称.老外很喜欢用人名来命名算法或者是定理,数学里就有一堆,什么高斯定理.欧拉函数什么的.但是中国人更倾向于从表意上来给一个概念命名,比如勾股定理.同余定理等等.之前觉得用人名命名很洋气,作者可以青史留名,后来想想这也是英文表意能力不足,很难用表意的方…
//KMP算法,匹配字符串模板 void getNext(int[] next, String t) { int n = next.length; for (int i = 1, j = 0; i < n; i++) { while (j > 0 && t.charAt(i) != t.charAt(j)) { j = next[j - 1]; } if (t.charAt(i) == t.charAt(j)) { j++; } next[i] = j; } } int kmp…
1 字符串匹配 字符串匹配是计算机的基本任务之一. 字符串匹配是什么?举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD"? 许多算法可以完成这个任务,Knuth-Morris-Pratt算法(简称KMP)是最常用的之一.它以三个发明者命名,起头的那个K就是著名科学家Donald Knuth(<计算机程序设计艺术>的作者). 2 KMP算法 这个算法不太容易理解,网上有很多解释,但…
直接接上篇上代码: //KMP算法 public class KMP { // 获取next数组的方法,根据给定的字符串求 public static int[] getNext(String sub) { int j = 1, k = 0; int[] next = new int[sub.length()]; next[0] = -1; // 这个是规定 next[1] = 0; // 这个也是规定 // while (j < sub.length() - 1) { if (sub.char…
本文主要的思路都是参考http://kb.cnblogs.com/page/176818/ 如有冒犯请告知,多谢. 一.KMP算法 KMP算法可以在O(n+m)的时间数量级上完成串的模式匹配操作,其基本思想是:每当匹配过程中出现字符串比较不等时,不需回溯指针,而是利用已经得到的"部分匹配"结果将模式向右"滑动"尽可能远的一段距离,继续进行比较.显然我们首先需要获取一个"部分匹配"的结果,该结果怎么计算呢? 二.算法分析 在上一篇中讲到了BF算法,…
处理字符串的过程中,难免会遇到字符匹配的问题.常用的字符匹配方法 1. 朴素模式匹配算法(Brute-Force算法) 求子串位置的定位函数Index( S, T, pos). 模式匹配:子串的定位操作通常称作串的模式匹配. 目标串:主串S. 模式串:子串T. 匹配成功:若存在T的每个字符依次和S中的一个连续字符序列相等,则称匹配成功.返回T中第一个字符在S中的位置. 匹配不成功:返回0.   lBrute-Force简称为BF算法,亦称简单匹配算法,其基本思路是: 从目标串s=“s1s2…sn…
源码:kmp.cpp // KMP.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <IOSTREAM> using namespace std; #define BUF_SIZE 100 #define BUF_SIZE_2 200 /*****************************************************…
字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD"? 许多算法可以完成这个任务,Knuth-Morris-Pratt算法(简称KMP)是最常用的之一.它以三个发明者命名,起头的那个K就是著名科学家Donald Knuth. 这种算法不太容易理解,网上有很多解释,但读起来都很费劲.直到读到Jake Boxer的文章,我才真正理解这种算法.下面,我用自己的语言…
KMP算法是用来解决字符串的匹配问题的,即在字符串S中寻找字符串P.形式定义:假设存在长度为n的字符数组S[0...n-1],长度为m的字符数组P[0...m-1],是否存在i,使得SiSi+1...Si+m-1等于P0P1...Pm-1,若存在,则匹配成功,若不存在则匹配失败.该问题经常出现在编辑器中,即常用的find或ctrl-F命令,所以字符串匹配算法的复杂度直接影响编辑器的效率. 首先考虑朴素字符串匹配的方法.其思想是:循环以字符数组S中的每一个字符作为起点,与字符数组P进行匹配.其代码…
一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中定位另一个串的高效算法.简单匹配算法的时间复杂度为O(m*n);KMP匹配算法.可以证明它的时间复杂度为O(m+n).. 一.简单匹配算法 先来看一个简单匹配算法的函数: int Index_BF ( char S [ ], char T [ ], int pos ) { /* 若串 S 中从第po…
如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在ababcd中找出abc.这里介绍算法思想,只给出了第一次出现的位置. 一.算法思想 传统算法是从匹配串第一字符开始和模式串比较,直到遇到不符合的字符,然后从匹配串的下一个字符开始,重复上面的过程.代码如下: void find(char t[],char p[]){ int m = strlen(t);…
假设主串:a b a b c a b c a c b a b      子串:a b c a c 1.一般匹配算法 逐个字符的比较,匹配过程如下: 第一趟匹配 a b a b c a b c a c b a b a b c 第二趟 a b a b c a b c a c b a b    a 第三趟 a b a b c a b c a c b a b     a b c a c 第四趟 a b a b c a b c a c b a b       a 第五趟 a b a b c a b c a…
KMP算法(研究总结,字符串) 前段时间学习KMP算法,感觉有些复杂,不过好歹是弄懂啦,简单地记录一下,方便以后自己回忆. 引入 首先我们来看一个例子,现在有两个字符串A和B,问你在A中是否有B,有几个?为了方便叙述,我们先给定两个字符串的值 A="abcaabababaa" B="abab" 那么普通的匹配是怎么操作的呢? 当然就是一位一位地比啦.(下面用蓝色表示已经匹配,黑色表示匹配失败) 但是我们发现这样匹配很浪费! 为什么这么说呢,我们看到第4步: 在第4步…
如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在ababcd中找出abc.这里介绍算法思想,只给出了第一次出现的位置. 一.算法思想 传统算法是从匹配串第一字符开始和模式串比较,直到遇到不符合的字符,然后从匹配串的下一个字符开始,重复上面的过程.代码如下: void find(char t[],char p[]){ int m = strlen(t);…