用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. 少部分图片来自孤~影 ...
随机推荐
- spring多数据源的配置(转)
C3P0和DBCP的区别 C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展.目前使用它的开源项目有Hibernate,Spring等. d ...
- row_number()、rank()、dense_rank()、ntile()
原文:row_number().rank().dense_rank().ntile() SQL2005中row_number()等函数的用法 2005比2000新增了几个函数,分别是row_numbe ...
- a web-based music player(GO + html5)
github 住址:https://github.com/codercheng/music-player 后台是用GO (windows/ linux 都能够),前端是HTML5 推荐用chrome浏 ...
- NSIS:在线下载并安装程序
原文 NSIS:在线下载并安装程序 看到有同学留言说需要这方面的代码,所以贴出以下代码供参考(非完整脚本).需要用NSISdl插件. Section -.NET Framework NSISdl ...
- NSIS皮肤插件
原文 NSIS皮肤插件 [有一个更好的皮肤,大家不妨试一下.http://www.flighty.cn/html/bushu/20110413_118.html ] 对于一般的安装不推荐使用皮肤,因为 ...
- python中and和or的使用方法
今天看了一个源代码,甚是对python不解,于是查了下资料,只是纠正下网上的老兄的解释 python 中的and从右到左计算表达式.若全部值均为真,则返回最后一个值.若存在假,返回第一个假值. or是 ...
- S3C2416裸机开发系列19_Fatfs播放录像wav音频文件
S3C2416裸机开发系列19 Fatfs播放录像wav音频文件 国际象棋男孩 1048272975 多媒体资源,一般都是以文件的形式存储在固化存储器中.Fatfs所支持的fat32为windo ...
- Cocos2d-x在线粒子编辑器
自由.其效果是非常赞,可以手动调节和.出口可以上网plist档!. 住址:http://particle2dx.com/
- 从JAR包中如何读取数据文件
还不是很懂.....待总结......
- 【Android先进】我们为什么要创建Activity基类Activity什么是一般的基类方法
今天,它可以被视为只是基本完成了其首个商业项目,在发展过程中,风格,然而随着工作经验的积累.最终開始慢慢的了解到抽象思想在面向对象编程中的重要性,这一篇简单的介绍一下我的一点收获. 首先,在如今的项目 ...