今天又看了一遍KMP,感觉真的懂了...就来这儿发一下心得吧.

KMP算法其实就是暴力的改进版.让我们看看暴力的匹配.

Original string: ababababcbbababababc
Pattern string:  abababc

步骤:

ababababcbbababababc
abababc
....中间一些步骤
ababababcbbababababc
abababc
这里a和c匹配不了了,传统的作法会从第二个字符`b'开始匹配.明显不行又跳出.即:
ababababcbbababababc
a...
再从第三个字符`a'开始:
ababababc...
abababc
现在匹配了.继续重复.

很明显这个算法在极端情况下的时间复杂度是$\text{O}\left( len\left( \text{Orig String} \right) \cdot len\left( \text{Patt String}\right)\right)$.效率很低.

想一想.在Brute Force中,每次失配后都会将Pattern的头指针指向下一个字符匹配,相当于每次失配都只能跳过一个字符.显然这么做效率非常低.能不能一次跳过多个字符却依然不会漏过匹配呢?当然可以.这样跳过的要求是什么呢?

看看这个例子:
ababababc
abababc
首先`a'和`c'不匹配.跳到`b'么?明显不行,不匹配.
注意到模式串中的
abababc
最前面的`ab'和无法匹配的`c'前面的`ab'是相同的.那么往前跳两格.为什么不跳四格呢?注意到
abababc
中,最前面也有`abab'.
原因是这两部分长度的和超过了已经匹配的字符串的长度,便也许会漏解.
那么在这时设置一个`f[i]'数组,表示第i位匹配失败后将i减小到几.
那么在这个例子中,`f[i]'值如下:(虚拟一个`s[i]'数组表示跳多远)
patt a b a b a b c
f[i] 0 0 0 1 2 3 0
s[i] 0 1 2 2 2 2 6
i 0 1 2 3 4 5 6
即s[i]=i-f[i]
那么如何求这个f数组呢?

这就是一个有意思的问题了.注意到模式串一般来说要比查找的串要短不少,因此用暴力的$\text{O}\left( n^2\right)$也算一种减小问题规模的算法.但是这样就不统一了,这个时间复杂度奇怪得很.注意到求这个数组的过程神似字符串匹配,那么我们可以用KMP自己来求解,即考察所有在它前面的字符中能够匹配的最大的串.这个可以用一种类似于动归的办法很方便的求解.

设已经求到第i位,那么第i+1位就能被方便的求解.(伪代码,p是模式串,下标从0开始)

f[0]=f[1]=0
j=f[i]
while j && p[i]!=p[j]:
j=f[j]
f[i+1]=j+1 if p[i]==p[j] or 0

最后附上代码

#include <string.h>
#include <malloc.h>
#include <stdio.h>
void getfail(char* p,int* f){
int m=strlen(p),i=1,j;
f[0]=f[1]=0;
for(;i<m-1;++i){
j=f[i];
while(j&&p[i]!=p[j]){
j=f[j];
}
f[i+1]=(p[i]==p[j]?++j:0);
}
}
int match(char* s,char* p,int* res){
int l=strlen(s),i,j,lp=strlen(p),lm=0;
int* f=(int*)malloc((lp+10)*sizeof(int));
if(f==NULL) return -2;
getfail(p,f);
j=0;
for(i=0;i<l;++i){
while(j&&p[j]!=s[i]) j=f[j];
if(p[j]==s[i]) ++j;
if(j==lp){
res[lm]=i-lp+1;
++lm;
j=f[j-1];
if(p[j]==s[i]) ++j;
}
}
return lm;
}

这段代码可以求出所有匹配字符串,并返回匹配数.

KMP算法心得的更多相关文章

  1. 学习KMP算法的一点小心得

    KMP算法应用于 在一篇有n个字母的文档中 查找某个想要查找的长度为m的单词:暴力枚举:从文档的前m个字母和单词对比,然后是第2到m+1个,然后是第3到m+2个:这样算法复杂度最坏就达到了O(m*n) ...

  2. 很详尽KMP算法(厉害)

    作者:July时间:最初写于2011年12月,2014年7月21日晚10点 全部删除重写成此文,随后的半个多月不断反复改进.后收录于新书<编程之法:面试和算法心得>第4.4节中. 1. 引 ...

  3. 子字符串查找之————关于KMP算法你不知道的事

    写在前面: (阅读本文前需要了解KMP算法的基本思路.另外,本着大道至简的思想,本文的所有例子都会做从头到尾的讲解) 作者翻阅了大量网上现有的KMP算法博客,发现广为流传的竟然是一种不完整的KMP算法 ...

  4. KMP算法 字符串匹配(看猫片)

    前言 此篇笔记根据自己的理解和练习心得来解释算法,只代表个人观点,如有不足请指出(我刚学QWQ) 浅谈字符串匹配 设想一个场景,假设你是一个净化网络语言环境的管理员,每天需要翻阅大量的文章和帖子来查找 ...

  5. 简单有效的kmp算法

    以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下“奥,它是做模式匹配的”这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(先不说 ...

  6. KMP算法

    KMP算法是字符串模式匹配当中最经典的算法,原来大二学数据结构的有讲,但是当时只是记住了原理,但不知道代码实现,今天终于是完成了KMP的代码实现.原理KMP的原理其实很简单,给定一个字符串和一个模式串 ...

  7. 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)

    前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...

  8. KMP算法实现

    链接:http://blog.csdn.net/joylnwang/article/details/6778316 KMP算法是一种很经典的字符串匹配算法,链接中的讲解已经是很明确得了,自己按照其讲解 ...

  9. 数据结构与算法JavaScript (五) 串(经典KMP算法)

    KMP算法和BM算法 KMP是前缀匹配和BM后缀匹配的经典算法,看得出来前缀匹配和后缀匹配的区别就仅仅在于比较的顺序不同 前缀匹配是指:模式串和母串的比较从左到右,模式串的移动也是从 左到右 后缀匹配 ...

随机推荐

  1. 第二章:Javascript词法结构

    编程语言的词法结构是一套基础性的规则,用来描述你如何编写这门语言.作为语法的基础,它规定了变量名是怎么样的,如何写注释,以及语句之间是如何区分的.本节用很短的篇幅来介绍javascript的词法结构. ...

  2. C#的默认访问修饰符

    Classes and structs that are not nested within other classes or structs can be either public or inte ...

  3. UIToolbar 如何调整里面的按钮位置

    可以在Bar Button Item后面填个Fixed Space Bar Button Item 或者Flexible Space Bar Button Item,然后再在后面加上下一个Bar Bu ...

  4. Html巩固

    1.html元素都支持全局属性(通用的属性)和事件属性.     a标签:定义一个超文本链接,链接到另一个超文本文件的! button:定义一个点击按钮,按钮是出发当前页面的事件.

  5. 【BZOJ 3282】Tree Link Cut Tree模板题

    知道了为什么要换根(changeroot),access后为什么有时要splay,以及LCT的其他操作,算是比较全面的啦吧,,, 现在才知道这些,,,真心弱,,, #include<cstdio ...

  6. hdu1217 floyd

    floyd一遍即可.如果floyd后值有变大就是 #include<map> #include<string> #include<stdio.h> #include ...

  7. Java 并发-任务执行.

    首先来看一下,任务的定义: 所谓的任务,就是抽象,离散的工作单位.你可以简单理解为代码级别的 (Runnable接口) 大多数并发应用程序都是围绕着任务进行管理的. 看一小段代码: package c ...

  8. TinyMCE(富文本编辑器)

    [转]TinyMCE(富文本编辑器)在Asp.Net中的使用方法 官网演示以及示例代码:https://www.tinymce.com/docs/demo/image-tools/ 转自:http:/ ...

  9. jQuery返回顶部代码组件

    非原创,拿来修改,样式可自定义,div,img都可以,效果如下: 下载地址:http://files.cnblogs.com/files/EasonJim/jquery.topback.rar 项目相 ...

  10. IDE 集成开发环境

    集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器.编译器.调试器和图形用户界面工具.集成了代码编写功能 ...