kmp算法

美妙的字符串之KMP算法

ぐ巨炮叔叔 提交于 2020-01-19 01:55:20
概述 讲解非常非常详细的KMP算法 在S串中查找P串的位置所在 暴力算法:S:i, P:j 若s[i] == p[j],i++,j++; 若s[i]!=p[j], i = i-(j-1)+1, j = 0; 之前的已匹配段回溯肯定导致失配,因为p[0]!=p[last(当前不匹配的j位置)-1]; KMP算法:i不回退,只需要移动j。 1. 对模式串进行处理:next[j]是不匹配时的j下一步回溯位置,取决于当前字符的字符串中有最大长度的相同前缀后缀。 2. 对模式串P的处理:i从0-plen-1,遍历得到next[], 当某个字符失配时,该字符对应的next值会告诉你下一步匹配中,模式串应该跳到那个位置,如果next[j] = 0或者-1,则跳到模式串的开头字符,若next[j] = k 且k>0,代表下次匹配跳到j之前的某个字符,而不是跳到开头,且具体调过来k个字符。 int next[1000000+100]; void kmp_pre(char x[], int n){ int i, j; i= 0; j = next[0] = -1; while(i < n){ while(j!=-1 && x[i]!=x[j]) j = next[j]; next[++i] = ++j; } } int KmpSearch(char *s, char *p){ int i =0;

最大最小表示法+kmp算法--hdu3374

蹲街弑〆低调 提交于 2020-01-18 00:12:28
题目链接: https://vjudge.net/problem/HDU-3374 Give you a string with length N, you can generate N strings by left shifts. For example let consider the string “SKYLONG”, we can generate seven strings: String Rank SKYLONG 1 KYLONGS 2 YLONGSK 3 LONGSKY 4 ONGSKYL 5 NGSKYLO 6 GSKYLON 7 and lexicographically first of them is GSKYLON, lexicographically last is YLONGSK, both of them appear only once. Your task is easy, calculate the lexicographically fisrt string’s Rank (if there are multiple answers, choose the smallest one), its times, lexicographically last string’s Rank (if there are multiple answers,

KMP算法 学习例题 POJ 3461Oulipo

余生颓废 提交于 2020-01-12 12:51:35
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 37971 Accepted: 15286 Description The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e' . He was a member of the Oulipo group. A quote from the book: Tout avait Pair normal, mais tout s’affirmait faux. Tout avait Fair normal, d’abord, puis surgissait l’inhumain, l’affolant. Il aurait voulu savoir où s’articulait l’association qui l’unissait au roman : stir son tapis, assaillant à tout instant son imagination, l’intuition d’un tabou, la vision d’un mal obscur, d’un quoi vacant, d’un non

KMP算法

烂漫一生 提交于 2020-01-10 11:58:04
字符串匹配 是计算机的基本任务之一。 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD"? 许多算法可以完成这个任务, Knuth-Morris-Pratt算法 (简称KMP)是最常用的之一。它以三个发明者命名,起头的那个K就是著名科学家Donald Knuth。 这种算法不太容易理解,网上有很多 解释 ,但读起来都很费劲。直到读到 Jake Boxer 的文章,我才真正理解这种算法。下面,我用自己的语言,试图写一篇比较好懂的KMP算法解释。 1. 首先,字符串"BBC ABCDAB ABCDABCDABDE"的第一个字符与搜索词"ABCDABD"的第一个字符,进行比较。因为B与A不匹配,所以搜索词后移一位。 2. 因为B与A不匹配,搜索词再往后移。 3. 就这样,直到字符串有一个字符,与搜索词的第一个字符相同为止。 4. 接着比较字符串和搜索词的下一个字符,还是相同。 5. 直到字符串有一个字符,与搜索词对应的字符不相同为止。 6. 这时,最自然的反应是,将搜索词整个后移一位,再从头逐个比较。这样做虽然可行,但是效率很差,因为你要把"搜索位置"移到已经比较过的位置,重比一遍。 7. 一个基本事实是,当空格与D不匹配时,你其实知道前面六个字符是"ABCDAB"。KMP算法的想法是,设法利用这个已知信息

kmp编码问题(c语言)

夙愿已清 提交于 2020-01-01 11:33:09
对于程序的语法报错问题,就是根据提示去找问题,不要自己瞎猜(猜的基本都是错的) 1.其中对于C语言的函数申明:extern int strStr(char * x, char * y) 如果根据提示查,根本就解决不了。 2.关于数据类型的不匹配问题也是需要根据提示来改正。 解决了语法编译的问题,但是还是不能输出结果: # include <stdio.h> # include <string.h> # include <stdlib.h> extern int strStr ( char * x , char * y ) ; extern int indexKMP ( char * x , char * y , int z ) ; int main ( ) { char * haystack = "sssdjiefon" ; char * needle = "st" ; int result = strStr ( haystack , needle ) ; return result ; } int strStr ( char * haystack , char * needle ) { int j = indexKMP ( haystack , needle , 1 ) ; return j ; } /** 数据结构中的伪代码是不符合语法的

KMP算法

自古美人都是妖i 提交于 2019-12-29 14:30:04
#include<iostream> #include<time.h> #include<string> using namespace std; void init(string ,string); void show(char [],int); int kmp(string ,string,int pos); void get_next(char*,int *); string s1,t1; int m,n; char *s; char *t; int *next; /*************************MAIN**************************************/ int main(int argc[],char*args[]) { double t=clock(); cout<<"找到位置为:"<<kmp("acbsabcaacabaabaabcacaabc","abaabca",1)<<endl; delete[] s; delete[] next; cout<<"耗时:"<<(clock()-t)/1000<<"毫秒!"<<endl; return 0; } /**********************++++NEXT++++********************************/ void get_next(char

(收藏)KMP算法的前缀next数组最通俗的解释

点点圈 提交于 2019-12-24 10:40:26
我们在一个母字符串中查找一个子字符串有很多方法。KMP是一种最常见的改进算法,它可以在匹配过程中失配的情况下,有效地多往后面跳几个字符,加快匹配速度。 当然我们可以看到这个算法针对的是子串有对称属性,如果有对称属性,那么就需要向前查找是否有可以再次匹配的内容。 在KMP算法中有个数组,叫做前缀数组,也有的叫next数组,每一个子串有一个固定的next数组,它记录着字符串匹配过程中失配情况下可以向前多跳几个字符,当然它描述的也是子串的对称程度,程度越高,值越大,当然之前可能出现再匹配的机会就更大。 这个next数组的求法是KMP算法的关键,但不是很好理解,我在这里用通俗的话解释一下,看到别的地方到处是数学公式推导,看得都蛋疼,这个篇文章仅贡献给不喜欢看数学公式又想理解KMP算法的同学。 1、用一个例子来解释,下面是一个子串的next数组的值,可以看到这个子串的对称程度很高,所以next值都比较大 位置i 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 前缀next[i] 0 0 0 0 1 2 3 1 2 3 4 5 6 7 4 0 子串 a g c t a g c a g c t a g c t g 申明一下:下面说的对称不是中心对称,而是中心字符块对称,比如不是abccba,而是abcabc这种对称。 (1)逐个查找对称串。 这个很简单

BF算法 + KMP算法

我们两清 提交于 2019-12-23 10:25:31
准备: 字符串比大小:比的就是字符串里每个字符的 ASCII码的大小 。(其实这样的比较没有多大的意义,我们关心的是字符串是否相等,即 匹配 等) 字符串的存储结构: 同线性表(顺序存储+链式存储)    顺序存储结构是一组地址连续的存储单元来存储字符串中的字符序列 ;按照预定义的大小,为每个定义的字符串变量分配一个固定长度的存储区,一般用定长数组来定义。——空间分配不灵活,但是字符串一般都是连在一起表述的,”断章取义“的情况并不多,所以习惯上我们还是会 直接定义一个足够长度的存储区来存储 。   链式存储结构   BF算法:   BoyFriend 、Brute Force   朴素的 模式匹配 算法,其核心思想是:   ——有两个字符串S和T,长度分别为N和M。首先S[1]和T[1]比较,若相等,则再比较S[2]和T[2],一直到T[M]为止;若S[1]和T[1]不等,则T向右移动一个字符位置,与S[2]进行比较,而后再依次进行比较。   ——该算法 最坏情况下要进行M*(N-M+1)次比较,时间复杂度为O(M*N) 。____效率低下。 (注:在这里S为主串,T为子串,这种子串的定位操作通常称作串的模式匹配)   存在回溯,需要重头来过,效率低下。 KMP算法:   克努特-莫里斯-普拉特算法,大大的 避免重复遍历 的情况( 避免不必要的回溯 )    问题由模式匹配串(子串

KMP算法思想及改进

久未见 提交于 2019-12-20 00:58:50
如何判断某字符串包含某字符串? 首先,我们需要了解一下朴素匹配算法,这个算法要求主串循环遍历,在遍历主串的时候,最差的情况是每匹配一个主串的字符,子串都需要匹配s次,因此假设主串为M(m),子串为S(s),那么时间复杂度O(n) = (m-s)*s + s,由此我们可以看到这个时间复杂度并不是很理想。 例如:下表中,主串第1个字符匹配后与之后的3个字符,一共匹配4次,然后第2个字符再进行类似的匹配,依次到结束 由此,Knuth,Morris,Pratt发明了一种更优秀的匹配方式,这种方式就是KMP算法。 KMP算法思想:保持主串M(m)不回溯,只移动S(s)子串,也就是主串匹配到某个字符如果不匹配的情况下,主串不会再回到之前与子串匹配的首个字符从其后一个字符开始,而是直接从当前不匹配的字符开始重新与子串匹配,子串则从next数组中查找,看回缩到哪一位,可能子串并非是从第1位开始的,而此算法最坏的情况下,最多M(m)的每个字符匹配两次,因此,此算法的时间复杂度为O(2m)。 例:下表,建议先了解next后再对比此表,第3位为2次是因为第一次与c匹配不等,然后S(s)回溯将A移动到M(m)的第三位再匹配一次,因此2次。 next数组的意义:在使用KMP算法中,我们会用到next这个数组,用来存储主串中不匹配字串,对应的字串位置会回溯到什么位置。 例1: 例2:(如果在j

字符串匹配的KMP算法

孤街浪徒 提交于 2019-12-17 08:31:53
原理 字符串匹配 是计算机的基本任务之一。 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD"? 许多算法可以完成这个任务, Knuth-Morris-Pratt算法 (简称KMP)是最常用的之一。它以三个发明者命名,起头的那个K就是著名科学家Donald Knuth。 这种算法不太容易理解,网上有很多 解释 ,但读起来都很费劲。直到读到 Jake Boxer 的文章,我才真正理解这种算法。下面,我用自己的语言,试图写一篇比较好懂的KMP算法解释。 1. 首先,字符串"BBC ABCDAB ABCDABCDABDE"的第一个字符与搜索词"ABCDABD"的第一个字符,进行比较。因为B与A不匹配,所以搜索词后移一位。 2. 因为B与A不匹配,搜索词再往后移。 3. 就这样,直到字符串有一个字符,与搜索词的第一个字符相同为止。 4. 接着比较字符串和搜索词的下一个字符,还是相同。 5. 直到字符串有一个字符,与搜索词对应的字符不相同为止。 6. 这时,最自然的反应是,将搜索词整个后移一位,再从头逐个比较。这样做虽然可行,但是效率很差,因为你要把"搜索位置"移到已经比较过的位置,重比一遍。 7. 一个基本事实是,当空格与D不匹配时,你其实知道前面六个字符是"ABCDAB"。KMP算法的想法是,设法利用这个已知信息