kmp

kmp字符串匹配

浪子不回头ぞ 提交于 2020-02-04 14:42:34
文章目录 1. what is kmp? 2.暴力算法 2.1 暴力中的暴力 2.2 暴力中的优化 3.kmp算法 3.1 数组定义 3.2 关于kmp难以理解的原因简要分析 3.3 next数组的预处理 3.4 next数组的应用 4. kmp时间复杂度证明 5.模板题代码 6.写在最后 1. what is kmp? k m p kmp k m p 是一种字符串匹配算法,用于在 s s s 串中找到所有连续子串 t t t 由K什么,M什么,P什么三个人提出,所以叫 k m p kmp k m p 2.暴力算法 2.1 暴力中的暴力 如果是暴力的做法,我们会怎么做? 就直接拿 s s s 的每一位当开头,然后往后走,就像这样 比如说我们现在我们要在 a b c a b a a b a b a a abcabaababaa a b c a b a a b a b a a 串中找 a b a b abab a b a b 那么暴力的做法显然就是这个样子的 但是这样肯定会很慢,复杂度 O ( ∣ s ∣ ⋅ ∣ t ∣ ) O(|s|\cdot |t|) O ( ∣ s ∣ ⋅ ∣ t ∣ ) 但是他慢在哪里了呢? 比如说在第四步的时候,我们发现a和c不匹配,但是我们接下来还是一步一步的跳到了第七步,但是因为第一个字符是a,很明显他不可能和b或者c匹配

kmp算法基础

谁都会走 提交于 2020-02-03 11:59:24
https://www.luogu.com.cn/problemnew/solution/P3375 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e6+10; 4 int kmp[maxn]; 5 char a[maxn],b[maxn]; 6 int main() 7 { 8 scanf("%s%s",a+1,b+1); 9 int lena=strlen(a+1); 10 int lenb=strlen(b+1); 11 int index=0; 12 for(int i=2;i<=lenb;i++){ 13 while(index&&b[i]!=b[index+1]) 14 index=kmp[index]; 15 if(b[index+1]==b[i]) index++; 16 kmp[i]=index; 17 } 18 index=0; 19 for(int i=1;i<=lena;i++){ 20 while(index>0&&b[index+1]!=a[i]) 21 index=kmp[index]; 22 if(b[index+1]==a[i]) 23 index++; 24 if(index==lenb) {cout<<i-lenb+1<<endl;index=kmp

【转载】从头到尾彻底理解KMP(2014年8月22日版)

空扰寡人 提交于 2020-02-02 14:16:48
从头到尾彻底理解KMP 作者:July 时间:最初写于2011年12月,2014年7月21日晚10点 全部删除重写成此文,随后的半个多月不断反复改进。后收录于 新书 《 编程之法:面试和算法心得 》第4.4节中。 1. 引言 本KMP原文最初写于2年多前的2011年12月,因当时初次接触KMP,思路混乱导致写也写得混乱。所以一直想找机会重新写下KMP,但苦于一直以来对KMP的理解始终不够,故才迟迟没有修改本文。 然近期因开了个 算法班 ,班上专门讲解数据结构、面试、算法,才再次仔细回顾了这个KMP,在综合了一些网友的理解、以及算法班的两位讲师朋友曹博、邹博的理解之后,写了9张PPT,发在微博上。随后,一不做二不休,索性将PPT上的内容整理到了本文之中(后来文章越写越完整,所含内容早已不再是九张PPT 那样简单了)。 KMP本身不复杂,但网上绝大部分的文章(包括本文的2011年版本)把它讲混乱了。下面,咱们从暴力匹配算法讲起,随后阐述KMP的流程 步骤、next 数组的简单求解 递推原理 代码求解,接着基于next 数组匹配,谈到有限状态自动机,next 数组的优化,KMP的时间复杂度分析,最后简要介绍两个KMP的扩展算法。 全文力图给你一个最为完整最为清晰的KMP,希望更多的人不再被KMP折磨或纠缠,不再被一些混乱的文章所混乱。有何疑问,欢迎随时留言评论,thanks。 2.

KMP算法

早过忘川 提交于 2020-02-02 14:09:17
KMP算法 KMP算法用于在文本串S内查找模式串P的出现位置 时间复杂度为O(M + N) 最大长度表 前缀和后缀 前缀:除了最后一个字符以外,一个字符串的全部头部组合 后缀:除了第一个字符以外,一个字符串的全部尾部集合 前缀后缀的最长公共元素长度 举例说明,假如模式串为 P = "ABCABD" 模式串 A B C A B D 最大前缀后缀公共元素长度 0 0 0 1 2 0 “A” :前缀为空集,后缀为空集,共有元素长度为0 “AB”:前缀为[A],后缀为[B],共有元素长度为0 “ABC”:前缀为[A, AB],后缀为[C, BC],共有长度为0 “ABCA”:前缀为[A, AB, ABC],后缀为[A, CA, BCA],共有长度为1 “ABCAB”:前缀为[A, AB, ABC, ABCA],后缀为[B, AB, CAB, BCAB],共有长度为2 “ABCABD”:前缀为[A, AB, ABC, ABCA, ABCAB],后缀为[D, BD, ABD, CABD, BCABD],共有长度为0 next数组 next数组是KMP算法的核心部分,其中 next[i] 的定义为: 在模板串P[0, i - 1]范围内的前缀后缀最长公共元素长度 根据定义可以知道next数组可以由最大长度表向右移动一位得到 为了计算方便 next[0] 通常设为 -1 示例 模板串 A B C

poj 3080 hdu 1238 暴力KMP解决

女生的网名这么多〃 提交于 2020-02-01 11:07:18
poj 3080 hdu 1238 暴力KMP解决 poj 3080 ,<—原题链接 hdu 1238 ,<—原题链接 题意 poj 3080 是说给你 n 个字符串,找出他们共有的最长字符串,但是如果找到的字符串长度小于 3 ,也算失败,并输出相应的语句,否者查找成功,输出找到的字符串。 hdu 1238 和上边的差不多,不同的是,找到的这个字符串 R 有可能不是这个 n 个字符串中某个字符串 T 的子串,但是如果 R 的逆串 R' 是 T 的子串的话,也算成功。 解题思路 这个题好像没看到什么更有效的方法,暴力枚举,数据量也比较小。 对于这两个题,我们的做法都是直接按照第一个字符串枚举所有的子串,然后看看剩下的字符串是不是都含有这个字符串,就这么简单,就这么直接,勇敢枚举吧少年。 代码实现 这两个代码真的是极其相似 //poj 3080 #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<stack> #include<queue> #include<map> using namespace std; const int MAXN=12; const int MAX_LEN=67; string

HDU[1358] Period 【KMP+循环节】

ぃ、小莉子 提交于 2020-02-01 09:20:08
Description For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the prefix is a periodic string. That is, for each i (2 <= i <= N) we want to know the largest K > 1 (if there is one) such that the prefix of S with length i can be written as , that is A concatenated K times, for some string A. Of course, we also want to know the period K. Input The input file consists of several test cases. Each test case consists of two lines. The first one contains N (2 <= N <= 1 000 000) – the size of the string S.

HDU - 6629 string matching(扩展KMP)

风格不统一 提交于 2020-01-31 02:52:38
题目链接: 点击查看 题目大意:给出一个字符串 s 和一个暴力程序,用于求解 s 的每个后缀和原字符串的最长公共前缀,现在问一共需要执行多少次比较操作 题目分析:首先肯定不能暴力去模拟,时间复杂度n*n,也不能用后缀数组,这个题好像特地卡了后缀数组的时间,倍增法nlogn会被卡掉,DC3因为常数太大也会被卡掉,网上说AC自动机会被卡内存,因为整个字符集是ASCII码的范围,那就只能用扩展KMP来求解了,扩展KMP在O(n)时间内求解出extend[ i ]数组,表示字符串 s 的每个后缀和字符串 t 匹配的最长公共前缀,这样一来就和这个题目对应上了,将字符串 t 的位置替换上字符串 s 就是答案了,记得特判一下每次匹配是否匹配到末尾,如果不是末尾需要加一,因为最后那次匹配失败也算一次匹配操作 代码: #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<queue> #include<map> #include<set> #include<sstream> using namespace std; typedef long long LL;

KMP入门 博客推荐+模板+入门习题

允我心安 提交于 2020-01-30 18:17:22
KMP入门 入门介绍 KMP入门博客推荐 next 数组讲解 模板代码 //这个是对next进行的优化 void getnext() //做的第一步是获得next【】的值 { int i=0,k=-1; next[0]=-1; while(i<lenb) { if(k==-1 || str[i]==str[k]) { i++; k++; if(t[i]==t[k]) next[i]=next[k]; else next[i]=k; } else k=next[k]; } } //没有带优化的部分 void getnext() //做的第一步是获得next【】的值 { int i=0,k=-1; next[0]=-1; while(i<lenb) { if (k==-1 || b[i]==b[k]) next[++i]=++k; else k=next[k]; } } int KMP() { getnext(); int i=0,j=0,cnt=0; while (i<lena) { if (j==-1||a[i]==b[j]) { i++;j++; } else j=next[j]; if (j==lenb) { cnt++; //记录一共有多少个匹配的字符串 printf("%d\n", i-j+1); //输出匹配的位置,从1开始的。 j=next[j];//接下来继续匹配 }

KMP算法

余生长醉 提交于 2020-01-29 20:56:27
A="abababaababacb",B="ababacb",我们来看看KMP是怎么工作的。我们用两个指针i和j分别表示,A[i-j+ 1..i]与B[1..j]完全相等。也就是说,i是不断增加的,随着i的增加j相应地变化,且j满足以A[i]结尾的长度为j的字符串正好匹配B串的前 j个字符(j当然越大越好),现在需要检验A[i+1]和B[j+1]的关系。当A[i+1]=B[j+1]时,i和j各加一;什么时候j=m了,我们就说B是A的子串(B串已经整完了),并且可以根据这时的i值算出匹配的位置。当A[i+1]<>B[j+1],KMP的策略是调整j的位置(减小j值)使得A[i-j+1..i]与B[1..j]保持匹配且新的B[j+1]恰好与A[i+1]匹配(从而使得i和j能继续增加)。我们看一看当 i=j=5时的情况。 i = 1 2 3 4 5 6 7 8 9 …… A = a b a b a b a a b a b … B = a b a b a c b j = 1 2 3 4 5 6 7 此时,A[6]<>B[6]。这表明,此时j不能等于5了,我们要把j改成比它小的值j'。j'可能是多少呢?仔细想一下,我们发现,j'必须要使得B[1..j]中的头j'个字母和末j'个字母完全相等(这样j变成了j'后才能继续保持i和j的性质)。这个j'当然要越大越好。在这里,B [1..5]=

POJ:3461-Oulipo(KMP模板题)

半腔热情 提交于 2020-01-29 04:59:38
原题传送: http://poj.org/problem?id=3461 Oulipo Time Limit: 1000MS Memory Limit: 65536K 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