Knuth-Morris-Pratt 字符串查找算法,简称为 “KMP算法”,常用于在一个文本串S内查找一个模式串P 的出现位置,这个算法由Donald Knuth、Vaughan Pratt、James H. Morris三人于1977年联合发表,故取这3人的姓氏命名此算法。

KMP算法对比暴力匹配算法的优势是:KMP算法通过分析模式串,找出模式串中相同的前缀和后缀,这样在匹配失败,移动模式串的时候,避免一些重复性的工作。

KMP算法的流程是:

  • 文本串S匹配到位置i,模式串P匹配到位置j

    • 如果j == -1,或者当前字符匹配成功,即S[i] == P[j],令i++,j++,继续匹配下一个字符
    • 如果j != -1,且当前字符不匹配,即S[i] != P[j],令i不变,j = next[j]。

      可以看出,kmp算法的关键在于计算出Next数组。

next数组对应的是模式串P。对next数组计算过程的理解,类似于归纳分析法。next数组中每一个元素的值,表示模式串P中该元素对应的字符前面的子字符串(不包括该位置的字符)中相同的前缀和后缀的长度。



next[0] = -1

next[j] = k

  • 如果P[k] == P[j],则next[j+1] = next[j] + 1 = k + 1
  • 如果P[k] != P[j],进行递归运算,如果P[next[k]] == P[j],则next[j + 1] = next[k] + 1,否则继续递归。

这是c版本的,别人的:

  1. int KmpSearch(char* s, char* p)
  2. {
  3. int i = 0;
  4. int j = 0;
  5. int sLen = strlen(s);
  6. int pLen = strlen(p);
  7. while (i < sLen && j < pLen)
  8. {
  9. //①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++
  10. if (j == -1 || s[i] == p[j])
  11. {
  12. i++;
  13. j++;
  14. }
  15. else
  16. {
  17. //②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]
  18. //next[j]即为j所对应的next值
  19. j = next[j];
  20. }
  21. }
  22. if (j == pLen)
  23. return i - j;
  24. else
  25. return -1;
  26. }
  27. void GetNext(char* p,int next[])
  28. {
  29. int pLen = strlen(p);
  30. next[0] = -1;
  31. int k = -1;
  32. int j = 0;
  33. while (j < pLen - 1)
  34. {
  35. //p[k]表示前缀,p[j]表示后缀
  36. if (k == -1 || p[j] == p[k])
  37. {
  38. ++k;
  39. ++j;
  40. next[j] = k;
  41. }
  42. else
  43. {
  44. k = next[k];
  45. }
  46. }
  47. }

我自己写了一个Erlang版本的:

  1. -module(kmp).
  2. -compile([export_all]).
  3. get_next(Pattern) ->
  4. Next = [-1],
  5. K = -1,
  6. J = 0,
  7. do_while(K, J, Next, Pattern).
  8. do_while(_K, J, Next, Pattern) when J >= length(Pattern) - 1->
  9. Next;
  10. do_while(K, J, Next, Pattern) ->
  11. case K =:= -1 orelse lists:nth(J + 1, Pattern) =:= lists:nth(K + 1, Pattern) of
  12. true ->
  13. K1 = K + 1,
  14. J1 = J + 1,
  15. NewNext = lists:append(Next, [K1]),
  16. do_while(K1, J1, NewNext, Pattern);
  17. false ->
  18. K1 = lists:nth(K + 1, Next),
  19. do_while(K1, J, Next, Pattern)
  20. end.
  21. kmpSearch(String, Pattern) ->
  22. SLen = length(String),
  23. PLen = length(Pattern),
  24. Next = get_next(Pattern),
  25. {SEnd, PEnd} = do_search(0, 0, SLen, PLen, String, Pattern, Next),
  26. Index = if PEnd =:= PLen ->
  27. SEnd - PEnd;
  28. true ->
  29. -1
  30. end,
  31. Index.
  32. do_search(I, J, SLen, PLen, String, Pattern, Next) when I < SLen , J < PLen ->
  33. case J =:= -1 orelse lists:nth(I + 1, String) =:= lists:nth(J + 1, Pattern) of
  34. true ->
  35. I1 = I + 1,
  36. J1 = J + 1,
  37. do_search(I1, J1, SLen, PLen, String, Pattern, Next);
  38. false ->
  39. J1 = lists:nth(J + 1, Next),
  40. do_search(I, J1, SLen, PLen, String, Pattern, Next)
  41. end;
  42. do_search(I, J, _SLen, _PLen, _String, _Pattern, _Next) ->
  43. {I, J}.

参考:

用erlang写的kmp算法的更多相关文章

  1. 一篇别人写的Kmp算法的讲解,多看多得

    kmp算法的理解与实现 博客分类: algorithms 算法      KMP算法曾被我戏称为看毛片算法,当时笑喷......大三那个时候硬着头皮把算法导论的kmp算法啃完,弄懂了kmp算法 的原理 ...

  2. KMP算法具体解释(转)

    作者:July. 出处:http://blog.csdn.net/v_JULY_v/. 引记 此前一天,一位MS的朋友邀我一起去与他讨论高速排序,红黑树,字典树,B树.后缀树,包含KMP算法,只有在解 ...

  3. 字符串模式匹配KMP算法

    一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...

  4. KMP算法小结

    最近看了一些关于KMP算法的资料,在此写一篇博客总计一下. 1.KMP算法介绍 KMP算法是一种字符串搜索的改进算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称 ...

  5. KMP hihoCoder1015 KMP算法

    人太蠢,,看了一天的KMP.. 刚開始看训练指南的,,后来才惊奇的发现原来刘汝佳写的f数组并非Next数组! 总认为和之前看过的全然不一样.. . 后来又百度了一下KMP,研究了非常久,然后用自己的逻 ...

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

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

  7. KMP算法详解(转自中学生OI写的。。ORZ!)

    KMP算法详解 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第六个自然段. 我们这里说的KMP不是拿来放电影的(虽然我很喜欢这个软件),而是一种算法.KMP算法是拿来处理字符串匹配的.换句 ...

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

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

  9. 算法:KMP算法

    算法:KMP排序 算法分析 KMP算法是一种快速的模式匹配算法.KMP是三位大师:D.E.Knuth.J.H.Morris和V.R.Pratt同时发现的,所以取首字母组成KMP. 少部分图片来自孤~影 ...

随机推荐

  1. matlab学习------------普通dialog对话框,错误对话框errordlg,警告对话框warndlg

    Dialog对话框 语法: h = dialog('PropertyName',PropertyValue,...) 对话框的默认属性 WindowStyle的值:   {normal} | moda ...

  2. OpenNMS在安装”我找不到jrrd.dll“错误的解决方法

    在Windows 2003 Server(虚拟机)安装OpenNMS.找不到jrrd.dll错误.尝试从学习OpenNMS官网下载jrrd-1.0.7.tar.gz,我们没有发现标dll文件,编译需要 ...

  3. 如何实现Web聊天

    假设你web聊天不知道这件事情,那么最好的方法可能是:openfire+jsjac openfire它是java做开源xmppserver,jsjac它是javascript做开源的Web版本xmpp ...

  4. vs2010模板修改

     使用visual studio 2010好久了,也遇到了不少问题,下面跟大家分享一些. 模板修改 说明: 主要工具: 以visual studio 2010作为例子,具体目录可能会根据不同的安装目录 ...

  5. myeclipse egit 安装失败 org.eclipse.e4.ui.css.swt.theme 0.0.0

    [前言] 首先确保您可能会被安装在阅读本文之前,myeclipse egit, 见文章:http://blog.csdn.net/uikoo9/article/details/17247405 事实上 ...

  6. 新的学生说说我是如何靠APP发展赢得了亿万

    郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠.支持郝萌主,捐赠数额任意.重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 14年踏入 ...

  7. hibernate Java 时间和日期类型 Hibernate 制图

    基础知识: 于 Java 于, 型表示的时间和日期包含: java.util.Date 和 java.util.Calendar. 外, 在 JDBC API 中还提供了 3 个扩展了 java.ut ...

  8. android怎么在launcher改动内置apk的icon

    找到launcher下的IconCache中加入变量用来存储要改动apk的包名 及要改动成的icon private String[] className = {"com.google.an ...

  9. java 面试题汇总(未完成)

    版权声明:本文博客原创文章,博客,未经同意,不得转载.

  10. 中国人被“清朝GDP世界第一”忽悠了!

    中国人被"清朝GDP世界第一"忽悠了!"鸦片战争前的清朝GDP世界第一",这一说法在中国流传非常广.追根溯源,最早提出这一观点的似乎是英国学者麦迪森,他的一项猜 ...