| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 5770 人关注过本帖, 2 人收藏
标题:[原创][分享]KMP的理解
只看楼主 加入收藏
nuciewth
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:我爱龙龙
等 级:贵宾
威 望:104
帖 子:9786
专家分:208
注 册:2006-5-23
结帖率:50%
收藏(2)
 问题点数:0 回复次数:11 
[原创][分享]KMP的理解
*/ --------------------------------------------------------------------------------------
*/ 出自: 编程中国 http://www.bc-cn.net
*/ 作者: nuciewth QQ:314218584
*/ 时间: 2007-9-13 编程论坛首发
*/ 声明: 尊重作者劳动,转载请保留本段文字
*/ --------------------------------------------------------------------------------------



今天看了一个上午的KMP,还算有点体会.拿出来一起分享一下,有什么不对的地方,请大家指正,谢谢.

前面I喜欢C斑竹 写过一个理解KMP的过程,写的蛮好,大家可以先去看一下.


假设:主串T,模式串P进行匹配,当匹配到T[r]!=P[i]时有:
[ P[0] ...P[i-1] ]=[ T[r-i] ...T[r-1] ]这两段是对应相等的.然而模式串也存在这样的匹配
[ P[0] ...P[k-1] ]=[ P[i-k]...P[i-1] ](这里的K即所谓的最长真前,后缀的大小)
很显然有:[ T[r-k] ... T[r-1]]=[ P[0] ... P[k-1] ]
这样我们就可以看出,下一次匹配应该是从 T[r]和P[k]开始比较(前面的k个字符已经匹配成功了).
所以主串不用进行回朔,提高了效率.
下面是个简单的图解,画的不好,凑合着参考一下.

图片附件: 游客没有浏览图片的权限,请 登录注册

现在关键是怎么求出当前这一步匹配的最长真前缀大小K.其实K就是模式串的自身模式匹配.
从红色部分的定义可以看出,K就是P[I]前M个字符(后缀)与P[]的最前面的M个字符(前缀)对应相等的最大值.
(M的最大值)而每次的K就构成了next[]数组.
我们规定next[0]=-1表示下一步将从p[0]和T[r+1]开始继续比较
next[i]=
{
:-1 //i==0
:MAX{ k | 0 < k< i } //[ P[0] ...P[k-1] ]=[ P[i-k]...P[i-1] ] }
:0 //其他情况
}

我想求next数组和匹配的算法应该可以不用写下来吧,大家对着书上看就行了,关键是理解为什么它不用回朔.




搜索更多相关主题的帖子: KMP 分享 
2007-09-13 21:29
nuciewth
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:我爱龙龙
等 级:贵宾
威 望:104
帖 子:9786
专家分:208
注 册:2006-5-23
收藏
得分:0 

倚天照海花无数,流水高山心自知。
2007-09-13 21:32
超级新手
Rank: 2
等 级:论坛游民
帖 子:185
专家分:59
注 册:2006-2-9
收藏
得分:0 
LZ的图不太好看。
下面是 网络上的文字,供参考 (作者不详)
a)KMP算法思路:
在matchStr中找是否含有patternStr子串: (这里字符串的实现用的是字符串的顺序表示)
1.a)外层的无回溯层:
将matchStr与patternStr进行比较:
1) 如果patternStr的当前位置与matchStr的当前位置不匹配:
1.1)若patternStr的当前位置为patternStr的首位置,则matchStr的位置直接加1.
1.2)若patternStr的当前位置不为patternStr的首位置,则matchStr的位置停在当前位置,patternStr的下标回溯到前面的一个恰当位置,利用next数组进行回溯.
2) 如果patternStr的当前位置与matchStr当前位置匹配,则tternStr和matchStr的位置均前进1.
3)当patternStr或matchStr的长度到达其长度时,跳出,否则继续做1,2.
4)如果matchStr达到其长度,则输出找到的位置,为matchPos-patternPos+1. 如果patternStr达到其长度,则输出没有找到的信息.
b)Next数组的实现思路:
Next数组主要是标志出一个字符数组的当前位置的最大真前,真后子缀的下标位置,这里采用了一个改进算法,为了配合1.2里的工作,让next数组里的下标尽可能的往前。



快快来我的群:13485998
学学C,玩玩算法,搞搞加密,比比谁更菜?
ARM恨死你。
2007-09-13 21:46
nuciewth
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:我爱龙龙
等 级:贵宾
威 望:104
帖 子:9786
专家分:208
注 册:2006-5-23
收藏
得分:0 

用WINDOWS自带的画图工具画的,鼠标难操作.是难看了.
你写的应该是算法的思路吧.


倚天照海花无数,流水高山心自知。
2007-09-13 22:09
wangwang168
Rank: 1
等 级:新手上路
帖 子:48
专家分:0
注 册:2007-5-8
收藏
得分:0 
关键是那个失败函数难以编写,其他还好

我有一个梦想
2007-09-17 23:14
nuciewth
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:我爱龙龙
等 级:贵宾
威 望:104
帖 子:9786
专家分:208
注 册:2006-5-23
收藏
得分:0 

求next[]数组不难.


倚天照海花无数,流水高山心自知。
2007-09-18 22:05
ibiancheng
Rank: 1
等 级:新手上路
帖 子:148
专家分:0
注 册:2007-4-3
收藏
得分:0 
“求next[]数组不难.”
好象就是求next[]难其他不难吧。。。

执著的信念,坚定的自信,勤奋的努力才是通向成功的捷径! !!
2007-11-08 18:52
ibiancheng
Rank: 1
等 级:新手上路
帖 子:148
专家分:0
注 册:2007-4-3
收藏
得分:0 

救命呀。。。
虽然你给我一个模式串,我能求出它的特征向量next[];
可怎么都总结不出来算法。。。
看不懂,书上算法是怎么求next[]的,好郁闷呀!

[此贴子已经被作者于2007-11-10 19:55:42编辑过]


执著的信念,坚定的自信,勤奋的努力才是通向成功的捷径! !!
2007-11-10 19:53
ibiancheng
Rank: 1
等 级:新手上路
帖 子:148
专家分:0
注 册:2007-4-3
收藏
得分:0 

顶,顶,顶,顶死楼主,爱死你了!
我昨晚把你这篇文章抄下来,挑灯在床上看,终于搞明白严老师书上的next[]数组的求法了!
谢谢啊

爱死你画的图了。。。
虽然不画图也知道这个关系,可是图就是比空想好!
再谢谢啊,我都高兴的要抓狂了!
(这几天一直都在想next[]的求法

[此贴子已经被作者于2007-11-11 10:24:08编辑过]


执著的信念,坚定的自信,勤奋的努力才是通向成功的捷径! !!
2007-11-11 10:21
conish
Rank: 1
等 级:新手上路
帖 子:31
专家分:0
注 册:2007-11-9
收藏
得分:0 
你们真都是强人啊,我看哪个算法都几个下午也只能明白是什么意思,要是自己编写肯定不会.
2007-11-24 20:29
快速回复:[原创][分享]KMP的理解
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.119842 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved