一、前言

kmp算法是用于从文本串text的字串中,寻找含有的模板串pattern的数量/位置的算法。

例如,在文本串abcabcccabc中,模板串abc的数量有3个,其起始位置是0,3,8。

二、思路

暴力是两个for循环O(n*m)搞定,显然不够优雅,而kmp则是O(n+m)

kmp说实话,有点绕,很多人不知道next数组的意义,但其实可以这样理解:

寻找模板串中最长的相同后缀与前缀,并通过next数组存储

如何理解?举个栗子

对于模板串abcab而言,我们从头开始构造next数组。

字串 前缀 后缀 最长公共前后缀 next数组
"a" [] [] next[0] = 0
"ab" [a] [b] next[1] = 0
"abc" [a,ab] [c,bc] next[2] = 0
"abca" [a,ab,abc] [a,ca,bca] a next[3] = 1
"abcab" [a,ab,abc,abca] [b,ab,cab,bcab] ab next[4] = 2
"abcabc" [a,ab,abc,abca,abcab] [c,bc,abc,cabc,bcabc] abc next[5] = 3

对于文本串abcabb来说,当匹配到5,即abcabb时,模板串匹配到abcabc,此时该位置字符不同

当使用暴力算法时,文本串必须跳回1位置,即b,而模板串必须跳回初始位置,重新匹配

当使用kmp算法时,模板串next[当前位置-1 = 4] = 2,即跳到2位置,此时模板串为abc,而文本串为abcabb

发现了吗?

模板串前缀abc与文本串后缀abb拥有相同前缀ab,于是文本串就不需要回到原点了,可以继续对比,即此时文本串为abcab,而模板串为ab,然后对比接下来的字符。

三、代码

int nextt[maxn];
void get_nextt(char pattern[]){//为pattern字符串创建nextt数组
nextt[0] = 0;
int max_length = 0;
for(int i = 1;pattern[i];i++){
while(max_length > 0 && pattern[max_length] != pattern[i])
max_length = nextt[max_length-1];
if(pattern[i] == pattern[max_length])
max_length++;
nextt[i] = max_length;
}
}
queue<int> search(char text[],char pattern[]){//从test字符串中,寻找含有多少个pattern字符串,并将其开头位置存入队列中
queue<int> q;
int pattern_length = strlen(pattern);
get_nextt(pattern);
int count = 0;
for(int i = 0;text[i];i++){
while(count > 0 && pattern[count] != text[i])
count = nextt[count-1];
if(pattern[count] == text[i])
count++;
if(count == pattern_length){
q.push(i-pattern_length+1 );
count = nextt[count-1];
}
}
return q;
}

字符串——kmp的更多相关文章

  1. hdu 5510 Bazinga(字符串kmp)

    Bazinga Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  2. hdu1686字符串kmp

    The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e ...

  3. 模板—字符串—KMP(单模式串,单文本串)

    模板—字符串—KMP(单模式串,单文本串) Code: #include <cstdio> #include <cstring> #include <algorithm& ...

  4. 字符串 --- KMP Eentend-Kmp 自动机 trie图 trie树 后缀树 后缀数组

    涉及到字符串的问题,无外乎这样一些算法和数据结构:自动机 KMP算法 Extend-KMP 后缀树 后缀数组 trie树 trie图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...

  5. 【poj 3080】Blue Jeans(字符串--KMP+暴力枚举+剪枝)

    题意:求n个串的字典序最小的最长公共子串. 解法:枚举第一个串的子串,与剩下的n-1个串KMP匹配,判断是否有这样的公共子串.从大长度开始枚举,找到了就break挺快的.而且KMP的作用就是匹配子串, ...

  6. 数据结构(复习)---------字符串-----KMP算法(转载)

    字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...

  7. 字符串(KMP):BZOJ 3670 [Noi2014]动物园

    3670: [Noi2014]动物园 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1521  Solved: 813[Submit][Status] ...

  8. HDU 4668 Finding string (解析字符串 + KMP)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题意:给出一个压缩后的串,以及一个模式串,问模式串 ...

  9. 流动python - 字符串KMP匹配

    首先我们看一下简单的字符串匹配. 你可以把文本字符串s固定,模式字符串p从s对齐的左边缘,作为承担部分完全一致,匹配成功,失败将是模式字符串p整体向右1地点,继续检查对齐部分,重复. #朴素匹配 de ...

  10. 查找子字符串----KMP算法深入剖析

    假设主串: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 ...

随机推荐

  1. Hive启动报错Terminal initialization failed; falling back to unsupported java.lang.Incomp

    这个报错需要删除hadoop目录下,需要删除下面目录下的文件,重启hadoop和hive即可 $HADOOP_HOME/share/hadoop/yarn/lib/jline-0.9.94.jar

  2. springboot项目下载文件功能中-切面-导致的下载文件失败的bug

    背景:使用spring提供的 ResponseEntity 和Resource结合,实现的下载文件功能 bug:Resource已经加载到了文件, 并且通过 ResponseEntity 构建了响应, ...

  3. [MySQL优化] -- 如何了解SQL的执行频率

    MySQL 客户端连接成功后,通过 show [session|global]status 命令 可以提供服务器状态信息,也可以在操作系统上使用 mysqladmin extended-status ...

  4. Rendering in UE4(Gnomon School UE4 大师课笔记)

    Rendering in UE4 Presented at the Gnomon School of VFX in January 2018, part two of the class offers ...

  5. 乱搞 - LCT求LCA

    神犇学弟说LCA要用LCT求,于是我就听他的话写了一个LCT~ Code: #include <bits/stdc++.h> #define N 500005 #define lson t ...

  6. Linux下更换为阿里yum源

    更新日期: 2018-08-06 1.yum源的工作原理 yum是为了解决安装包的依赖关系而生的,如果要源码安装一个软件,需要频繁下载各个包,并解决包的依赖关系.这就好比学门课程,要学会这门课程,就要 ...

  7. Java基础__Java中集合类

    ArrayList:有序.可重复.线程不安全.内部使用数组进行存储 LinkedList:有序.可重复.线程不安全.内部使用引用进行存储[可以很方便的进行插入.删除数据] Vector:有序.可重复. ...

  8. python中的break continue用法

    Break break跳出循环,并且终止最小封闭循环. Continue continue跳过本次循环,继续执行下一次的循环. 二者区别就是break会终止循环,continue不终止循环.

  9. Android解决AVD Hardware Buttons 和DPAD无法使用问题

    如图所示按键用鼠标点击时无法响应. 解决方案: 以我创建的AVD名为Tablet为例 1.找到用户目录(我的用户目录yummy),然后进入如下目录 mac: ~/yummy/.android/avd/ ...

  10. CefGlue获取网页源代码

    1.编写一个CefStringVisitor类: public class MyStringVisitor : CefStringVisitor { private readonly TaskComp ...