用erlang写的kmp算法
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版本的,别人的:
int KmpSearch(char* s, char* p)
{
int i = 0;
int j = 0;
int sLen = strlen(s);
int pLen = strlen(p);
while (i < sLen && j < pLen)
{
//①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++
if (j == -1 || s[i] == p[j])
{
i++;
j++;
}
else
{
//②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]
//next[j]即为j所对应的next值
j = next[j];
}
}
if (j == pLen)
return i - j;
else
return -1;
}
void GetNext(char* p,int next[])
{
int pLen = strlen(p);
next[0] = -1;
int k = -1;
int j = 0;
while (j < pLen - 1)
{
//p[k]表示前缀,p[j]表示后缀
if (k == -1 || p[j] == p[k])
{
++k;
++j;
next[j] = k;
}
else
{
k = next[k];
}
}
}
我自己写了一个Erlang版本的:
-module(kmp).
-compile([export_all]).
get_next(Pattern) ->
Next = [-1],
K = -1,
J = 0,
do_while(K, J, Next, Pattern).
do_while(_K, J, Next, Pattern) when J >= length(Pattern) - 1->
Next;
do_while(K, J, Next, Pattern) ->
case K =:= -1 orelse lists:nth(J + 1, Pattern) =:= lists:nth(K + 1, Pattern) of
true ->
K1 = K + 1,
J1 = J + 1,
NewNext = lists:append(Next, [K1]),
do_while(K1, J1, NewNext, Pattern);
false ->
K1 = lists:nth(K + 1, Next),
do_while(K1, J, Next, Pattern)
end.
kmpSearch(String, Pattern) ->
SLen = length(String),
PLen = length(Pattern),
Next = get_next(Pattern),
{SEnd, PEnd} = do_search(0, 0, SLen, PLen, String, Pattern, Next),
Index = if PEnd =:= PLen ->
SEnd - PEnd;
true ->
-1
end,
Index.
do_search(I, J, SLen, PLen, String, Pattern, Next) when I < SLen , J < PLen ->
case J =:= -1 orelse lists:nth(I + 1, String) =:= lists:nth(J + 1, Pattern) of
true ->
I1 = I + 1,
J1 = J + 1,
do_search(I1, J1, SLen, PLen, String, Pattern, Next);
false ->
J1 = lists:nth(J + 1, Next),
do_search(I, J1, SLen, PLen, String, Pattern, Next)
end;
do_search(I, J, _SLen, _PLen, _String, _Pattern, _Next) ->
{I, J}.
参考:
- http://blog.csdn.net/v_july_v/article/details/7041827
- http://www.jianshu.com/p/e2bd1ee482c3
- http://www.jianshu.com/p/9d068872913e
用erlang写的kmp算法的更多相关文章
- 一篇别人写的Kmp算法的讲解,多看多得
kmp算法的理解与实现 博客分类: algorithms 算法 KMP算法曾被我戏称为看毛片算法,当时笑喷......大三那个时候硬着头皮把算法导论的kmp算法啃完,弄懂了kmp算法 的原理 ...
- KMP算法具体解释(转)
作者:July. 出处:http://blog.csdn.net/v_JULY_v/. 引记 此前一天,一位MS的朋友邀我一起去与他讨论高速排序,红黑树,字典树,B树.后缀树,包含KMP算法,只有在解 ...
- 字符串模式匹配KMP算法
一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...
- KMP算法小结
最近看了一些关于KMP算法的资料,在此写一篇博客总计一下. 1.KMP算法介绍 KMP算法是一种字符串搜索的改进算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称 ...
- KMP hihoCoder1015 KMP算法
人太蠢,,看了一天的KMP.. 刚開始看训练指南的,,后来才惊奇的发现原来刘汝佳写的f数组并非Next数组! 总认为和之前看过的全然不一样.. . 后来又百度了一下KMP,研究了非常久,然后用自己的逻 ...
- Linux GCC下strstr的实现以及一个简单的Kmp算法的接口
今天做了一道题,要用判断一个字符串是否是另一个字符串的子串,于是查了一下strstr的实现. 代码如下: char *strstr(const char*s1,const char*s2) { con ...
- KMP算法详解(转自中学生OI写的。。ORZ!)
KMP算法详解 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第六个自然段. 我们这里说的KMP不是拿来放电影的(虽然我很喜欢这个软件),而是一种算法.KMP算法是拿来处理字符串匹配的.换句 ...
- 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)
前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...
- 算法:KMP算法
算法:KMP排序 算法分析 KMP算法是一种快速的模式匹配算法.KMP是三位大师:D.E.Knuth.J.H.Morris和V.R.Pratt同时发现的,所以取首字母组成KMP. 少部分图片来自孤~影 ...
随机推荐
- matlab学习------------普通dialog对话框,错误对话框errordlg,警告对话框warndlg
Dialog对话框 语法: h = dialog('PropertyName',PropertyValue,...) 对话框的默认属性 WindowStyle的值: {normal} | moda ...
- OpenNMS在安装”我找不到jrrd.dll“错误的解决方法
在Windows 2003 Server(虚拟机)安装OpenNMS.找不到jrrd.dll错误.尝试从学习OpenNMS官网下载jrrd-1.0.7.tar.gz,我们没有发现标dll文件,编译需要 ...
- 如何实现Web聊天
假设你web聊天不知道这件事情,那么最好的方法可能是:openfire+jsjac openfire它是java做开源xmppserver,jsjac它是javascript做开源的Web版本xmpp ...
- vs2010模板修改
使用visual studio 2010好久了,也遇到了不少问题,下面跟大家分享一些. 模板修改 说明: 主要工具: 以visual studio 2010作为例子,具体目录可能会根据不同的安装目录 ...
- myeclipse egit 安装失败 org.eclipse.e4.ui.css.swt.theme 0.0.0
[前言] 首先确保您可能会被安装在阅读本文之前,myeclipse egit, 见文章:http://blog.csdn.net/uikoo9/article/details/17247405 事实上 ...
- 新的学生说说我是如何靠APP发展赢得了亿万
郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠.支持郝萌主,捐赠数额任意.重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 14年踏入 ...
- hibernate Java 时间和日期类型 Hibernate 制图
基础知识: 于 Java 于, 型表示的时间和日期包含: java.util.Date 和 java.util.Calendar. 外, 在 JDBC API 中还提供了 3 个扩展了 java.ut ...
- android怎么在launcher改动内置apk的icon
找到launcher下的IconCache中加入变量用来存储要改动apk的包名 及要改动成的icon private String[] className = {"com.google.an ...
- java 面试题汇总(未完成)
版权声明:本文博客原创文章,博客,未经同意,不得转载.
- 中国人被“清朝GDP世界第一”忽悠了!
中国人被"清朝GDP世界第一"忽悠了!"鸦片战争前的清朝GDP世界第一",这一说法在中国流传非常广.追根溯源,最早提出这一观点的似乎是英国学者麦迪森,他的一项猜 ...