字符串——kmp
一、前言
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的更多相关文章
- hdu 5510 Bazinga(字符串kmp)
Bazinga Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- hdu1686字符串kmp
The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e ...
- 模板—字符串—KMP(单模式串,单文本串)
模板—字符串—KMP(单模式串,单文本串) Code: #include <cstdio> #include <cstring> #include <algorithm& ...
- 字符串 --- KMP Eentend-Kmp 自动机 trie图 trie树 后缀树 后缀数组
涉及到字符串的问题,无外乎这样一些算法和数据结构:自动机 KMP算法 Extend-KMP 后缀树 后缀数组 trie树 trie图及其应用.当然这些都是比较高级的数据结构和算法,而这里面最常用和最熟 ...
- 【poj 3080】Blue Jeans(字符串--KMP+暴力枚举+剪枝)
题意:求n个串的字典序最小的最长公共子串. 解法:枚举第一个串的子串,与剩下的n-1个串KMP匹配,判断是否有这样的公共子串.从大长度开始枚举,找到了就break挺快的.而且KMP的作用就是匹配子串, ...
- 数据结构(复习)---------字符串-----KMP算法(转载)
字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...
- 字符串(KMP):BZOJ 3670 [Noi2014]动物园
3670: [Noi2014]动物园 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1521 Solved: 813[Submit][Status] ...
- HDU 4668 Finding string (解析字符串 + KMP)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 题意:给出一个压缩后的串,以及一个模式串,问模式串 ...
- 流动python - 字符串KMP匹配
首先我们看一下简单的字符串匹配. 你可以把文本字符串s固定,模式字符串p从s对齐的左边缘,作为承担部分完全一致,匹配成功,失败将是模式字符串p整体向右1地点,继续检查对齐部分,重复. #朴素匹配 de ...
- 查找子字符串----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 ...
随机推荐
- onpageshow、onpagehide、onload、onunload
onpageshow :在用户浏览网页时触发, 在页面从浏览器缓存中读取时也触发 通过event.persisted 来判断, 如果页面从浏览器的缓存中读取该属性返回 ture,否则返回 false ...
- vue2 练习
table标签的frame和rules属性,可以控制边框的显示.frame属性控制着表格最外围的四条边框的可见性,而 rules 则控制着表格内部边框的可见性. frame属性可取的值及含义如下: * ...
- 【DES加密解密】 C#&JAVA通用
DES加密解密 C# Code /// <summary> /// DES加密解密帮助类 /// </summary> public static class DESHelpe ...
- XHTML测试题
1.XHTML 指的是? A.EXtra Hyperlinks and Text Markup Language B.EXtensible HyperText Marking Language C.E ...
- C语言位运算题解
#include <stdio.h> #include <stdlib.h> #include <string.h> //#define NONBLANK 1 ma ...
- QT5 网络通讯
QT5 TCP网络通讯 服务器与客户端建立连接listen() - connectToHost(); 触发newPendingConnect信号 实时数据通讯write(); read(); 触发 ...
- 关于tensorflow里面的tf.contrib.rnn.BasicLSTMCell 中num_units参数问题
这里的num_units参数并不是指这一层油多少个相互独立的时序lstm,而是lstm单元内部的几个门的参数,这几个门其实内部是一个神经网络,答案来自知乎: class TRNNConfig(obje ...
- find命令计算代码行数
[anonymous@localhost ~/lvs/ipvsadm- -regex '.*Makefile.*' -o -regex '.*\.[ch]' -exec cat {} \; | wc ...
- js base64编码,C#解码
JS: this.Base64 = function (str) { return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, fu ...
- python 快速排序-代码示例
def quick_sort(alist, first, last): if first >= last: # 如果开始等于结尾,即就一个元素 return mid_value = alist[ ...