前言

虽从事企业应用的设计与开发,闲暇之时,还是偶尔涉猎数学和算法的东西,本篇根据个人角度来写一点关于KMP串匹配的东西,一方面向伟人致敬,另一方面也是练练手,头脑风暴。我在自娱自乐,路过的朋友别太认真,嘿

背景

目标串: T(1…..n)

模式串: P(1…..m)

输出:搜索P在T中的位置 s,令 T(s…s+m-1) === P(1…m)

例如:

a g c t a g c a g c t a g c t g中查找a g c t g 返回 12(从1计数)

资料

资料太多了,我在此不准备进行深入分析整个推算过程,所以本篇文章只写给自己看

E文好理解能力好的直接去看原篇论文《Fast Pattern Matching in Strings》

主要思想参考这里:

字符串匹配的KMP算法(阮一峰)

主要实现参考这里:

http://blog.csdn.net/yearn520/article/details/6729426

http://biaobiaoqi.me/blog/2013/05/25/kmp-algorithm/

笨拙的大脑

我和很多普通人一样,对于此类问题,大脑中的第一反应时朴素暴力匹配法

  • 假设T从i处开始迭代索引
  • 比较失配时,使用回溯法,将P相对于T右移1位,然后T的迭代索引回溯到i+1,重新匹配
  • 缺陷:重复的移动操作,重复的比较匹配操作
  • 效率:移动操作为(n-m),比较操作为m,数量级O(n*m)

优化的KMP

KMP的核心思想是,利用模式串进行自我匹配,生成前缀数组,优化移动和匹配操作

  • 目标串无须回溯,只需要移动模式串即可,节省移动操作
  • 重复的匹配可以省略,节省了匹配操作,大概列两种极端的例子
  • 额外的空间开销O(m)(存储nexts数组),线性时间开销 O(n+m)

难点

算法的关键和难点在于计算前缀数组next[]

实现

  • 前缀数组next实现
static void SetPrefix(IList<char> pattern, int[] nexts)
{
nexts[0] = 0;
int m = pattern.Count;
for (int i = 1; i < m; i++)
{
int k = nexts[i - 1];
while (pattern[i] != pattern[k] && k != 0)
{
k = nexts[k - 1];
}
if (pattern[i] == pattern[k])
nexts[i] = k + 1;
else
nexts[i] = 0;
}
}
  • KMP匹配方法实现
static IEnumerable<int> KMP(string text, string pattern)
{
int[] nexts = new int[pattern.Length]; int n = text.Length;
int m = pattern.Length; SetPrefix(pattern.ToList(), nexts); for (int i = 0, j = 0; i < n; i++)
{
while (j > 0 && text[i] != pattern[j])
j = nexts[j - 1]; if (text[i] == pattern[j])
j++; if (j == m)
yield return i - m + 1;
} yield break;
}

待续

下面列一些字符串模式匹配的其他算法,以后有时间好好研究和实现

结语

关于串匹配的算法还有很多,关于KMP的改进实现也有很多,时间和精力有限,以后有时间再深入!

KMP算法简单回顾的更多相关文章

  1. KMP 算法简单解释

    ​ 讲KMP算法,离不开BF,实际上,KMP就是BF升级版,主要流程和BF一样 ​ 不同是在匹配失败时能利用子串的特征减少回溯,利用根据子串特征生成的Next数组来减少 <( ̄︶ ̄)↗[GO!] ...

  2. 串的应用与kmp算法讲解--学习笔记

    串的应用与kmp算法讲解 1. 写作目的 平时学习总结的学习笔记,方便自己理解加深印象.同时希望可以帮到正在学习这方面知识的同学,可以相互学习.新手上路请多关照,如果问题还请不吝赐教. 2. 串的逻辑 ...

  3. 简单有效的kmp算法

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

  4. 简单kmp算法(poj3461)

    题目简述: 给你两个字符串p和s,求出p在s中出现的次数. 思路简述: 在介绍看BF算法时,终于了解到了大名鼎鼎的KMP算法,结果属于KMP从入门到放弃系列,后来看了几位大神的博客,似乎有点懂了.此题 ...

  5. KMP算法实践与简单分析

    一.理解next数组 1.约定next[0]=-1,同时可以假想在sub串的最前面有一个通配符"*",能够任意匹配.对应实际的代码t<0时的处理情况. 2.next[j]可以 ...

  6. 运用kmp算法解决的一些问题的简单题解

    学习kmp算法我最后是看的数据结构书上的一本教材学会的..我认为kmp相对于普通的BF算法就是避免了非常多不必要的匹配.而kmp算法的精髓自然就在于next数组的运用...而next数组简而言之就是存 ...

  7. KMP算法的一个简单实现

    今天学习KMP算法,参考网上内容,实现算法,摘录网页内容并记录自己的实现如下: 原文出处: http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93M ...

  8. KMP算法 C#实现 字符串查找简单实现

    KMP算法 的C#实现,初级版本 static void Main(string[] args) { #region 随机字符 StringBuilder sb = new StringBuilder ...

  9. Linux GCC下strstr的实现以及一个简单的Kmp算法的接口

    今天做了一道题,要用判断一个字符串是否是另一个字符串的子串,于是查了一下strstr的实现. 代码如下: char *strstr(const char*s1,const char*s2) { con ...

随机推荐

  1. (大数据工程师学习路径)第一步 Linux 基础入门----正则表达式基础

    介绍 虽然我们这一节的标题是正则表达式,但实际这一节只是介绍grep,sed,awk这三个命令,而正则表达式作为这三个命令的一种使用方式(命令输出中可以包含正则表达式).正则表达式本身的内容很多,要把 ...

  2. JavaEE(11) - 消息驱动EJB

    1. MDB作为异步消费者的本质 2. MDB的运行机制 3. 使用@MessageDriven修饰MDB(需要messageListenerInterface) 4. 实现MessageListen ...

  3. 《高性能 JavaScript》读书笔记(一)

    一. 加载和执行——优化JavaScript规则: 1. 将脚本放在底部:2. 减少页面中外链脚本文件的数量: 比如,下载单个100kb的文件将比下载4个25kb的文件更快.这个可以通过离线打包工具或 ...

  4. acd - 1216 - Beautiful People(DLIS)

    意甲冠军:一个人有两个属性S, B(1 ≤ Si, Bi ≤ 10^9),当两个人满足这两个属性 S1 < S2 && B1 < B2 要么 S1 > S2 & ...

  5. SpringMVC访问静态资源[转]

    1.如果只配置拦截类似于*.do格式的url,则对静态资源的访问是没有问题的,如下: <!-- SpringMVC核心分发器 --> <servlet> <servlet ...

  6. mac github工具将命令当下来的代码拖入macgithub中就可以

    mac github工具将命令当下来的代码拖入macgithub中就可以,刚開始傻傻的就知道点击那个加入button,总是在当下来的文件夹下创建个文件夹.并且代码不能同步

  7. android--解--它们的定义tabhost(动态添加的选项+用自己的主动性横向滑动标签+手势切换标签页和内容特征)

    在本文中,解决他们自己的定义tabhost实现,并通过代码集成动态加入标签功能.自己主动标签横向滑动功能.和手势标签按功能之间切换. 我完成了这个完美的解决方案一起以下: 1.定义tabwidget布 ...

  8. 用fcntl()设置堵塞函数的堵塞性质

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types. ...

  9. C#操作Excel初探

        近期一段时间正好在做winform导出Excel报表的问题,学习了一下C#操作Excel的一些方法(如:向Excel中插入图片:删除Excel指定sheet中的某行或某列,在Excel指定的单 ...

  10. Android:仿手机QQ朋友动态ListView

    1.介绍: 使用此博客XListView模仿Android版本QQ朋友动态ListView效果.效果如下面的截图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZ ...