[散分]学习KMP模式的一些自我思路, 希望对大家有点帮助[散分]

lin_style 2006-10-30 08:47:29
KMP字符串模式匹配

什么是KMP字符串模:通俗点说就是一种在一个字符串中定位另一个串的高效算法

这里就不提简单匹配算法了,只把我自己学习KMP一点思路提供出来。

总结一句就是,将字符前几个字段和后面字段对应起来,查找时只需要根据后面的字段就可以知道是

否和后面的字段相等。

我们将这个条件模式的值称为模式值next[n],n称为要匹配的点,接着再定义一个k,设为要匹配的段,再记住一点,是从左到右的匹配字符串

先看定义:


(1)next[0]= -1 意义:任何串的第一个字符的模式值规定为-1。

(2)next[j]= -1 意义:模式串T中下标为j的字符,如果与首字符

相同,且j的前面的1—k个字符与开头的1—k

个字符不等(或者相等但T[k]==T[j])(1≤k<j)。

如:T=”abCabCad” 则 next[6]=-1,因T[3]=T[6]

(3)next[j]=k 意义:模式串T中下标为j的字符,如果j的前面k个

字符与开头的k个字符相等,且T[j] != T[k] (1≤k<j)。

即T[0]T[1]T[2]。。。T[k-1]==

T[j-k]T[j-k+1]T[j-k+2]…T[j-1]

且T[j] != T[k].(1≤k<j);

(4) next[j]=0 意义:除(1)(2)(3)的其他情况。

不要被这吓倒,前面说过,KMP核心就是将字符前几个字段和后面字段对应起来。

我们将一个字符段分为头,中间,尾巴来分析。

头位置分为0,1点

0点:任何串的第一个字符的模式值规定为-1。

1点:next[1]=0 根据 (4) 因(3)有1<=k<j;不能说,j=1,T[j-1]==T[0]

以上两点都为固定,记住即可。

接着看中间的匹配模式,可以有A A、AAA AAA、匹配,这属一类。或者AAB AAC这样的前两个匹配。

疑问,为什么没有ACA ABA的匹配- ①

首先解释“模式串T中下标为j的字符,如果与首字符相同,且j的前面的1—k个字符与开头的1—k个字符不等”

按我们的思路旋转,可有以下匹配,可从单字开始 j=1;

ABBCA

单进行判断多字匹配时,注意,第一个A成为第一个字符串的首字,第二个A成为第二个字符串的尾字,判断他们是否相等,(假设J=2,两个字符),只需要判断C
(第二个字段的第一个首字)和第一个A(第一个字符串的首字)是否相等,即,第一点里面所说j的前面的1—k个字符与开头的1—k个字符不等。


接着解释多字匹配,当j的前面的1—k个字符与开头的1—k个字符相等时,还差最后一个字符K和J,这时候只需要判断他们是否相等,就可知这个字段是否匹配,即

且j的前面的1—k个字符与开头的1—k个字符相等或T[k]==T[j]。


最后解释第三种匹配,AAB AAC型匹配。有了前面多字匹配,就很容易解释j的前面k个字符与开头的k个字符相等,最后个字符不等的这句。

我对思路总结是,进行匹配时,先检查单字是否匹配,If 不匹配,对K进行递增值化,看看是否满足第三种
{
else 匹配
{
如果匹配,对J-K+1的位置和字符串第一个位置进行比较,
elseif如果不满足,则满足单字匹配,
elseif如果满足,继续比较下去,全等的话就是AAA AAA形式,否则回到单字匹配
}
}
--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------

实战
求T=“a b c a c”的模式函数的值。
0 1 2 3 4

next[0]= -1 根据(1)

next[1]=0 根据 (4) 因(3)有1<=k<j;不能说,j=1,T[j-1]==T[0]

next[2]=0 根据 (4) 因(3)有1<=k<j;(T[0]=a)!=(T[1]=b)

next[3]= -1 根据 (2)

next[4]=1 根据 (3) T[0]=T[3] 且 T[1]=T[4]


解释[2]:j=2,k最大取值1。 a c单字匹配不成功,取4

解释[3]:J=3,{k|1,2} 单字匹配成功,由于K最大取到2,所以字符长度最大为2,取两个字符ab和ca,c不等于a,匹配失败,满足第二种形态的单匹配

解释[4]:J=4,{K|1,2,3,}单字匹配不成功,将K自加1,这时候最到取到2,取字符ab和ac,相等,K再加1,最大长度取到3,比较abc=cac,头字符a不等于c,退出
,选择ab,ac作为第三种匹配。


将这个原理掌握后,下面的就很简单了。

不在本文提及范围中。。




以上资料是在下闷了个下午闷出来的。 没有问任何人和查阅资料,所以不知道网上其他的思路。如有雷同,真的是属巧合。

另,因本人学历原因(专科大二),文中一些术语的地方可能说得不当 ,请高手指教。

再另,欢迎等年级人士交流,QQ242106764,注明CSDN
...全文
543 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixing979 2006-12-15
  • 打赏
  • 举报
回复
顶一下
wanphonguo 2006-11-29
  • 打赏
  • 举报
回复
接分
LiChenYue 2006-11-28
  • 打赏
  • 举报
回复
散分必顶!
chllcy 2006-11-27
  • 打赏
  • 举报
回复
mark
wlj1800 2006-11-22
  • 打赏
  • 举报
回复
记得上学的时候学习字符匹配是这样子的,首先分析子串看子串中是否存在于子串本身开始相同的串存在,如果有则将其纪录后变使用。例如:如果子串是12312546则他们分别对应得值为:1(-1)2(1)3(1)1(-1)2(1)5(3)4(1)6(1)也就是说当子串与主串匹配时,如果长串与子串首个1不匹配就将长串后移动1为,首个人不匹配就将长串不动,子串用手子母与其匹配,一次类推。括号内表示的是自串合成串一动的位置。-1表主串移动,其他表示子串移动,不过好久没看数了,估计很多错误的地方,建议大家去看下严蔚敏的《数据结构》C#版本的。80页说的非常清楚。
LuckilyYu 2006-11-21
  • 打赏
  • 举报
回复
mark
aniude 2006-11-21
  • 打赏
  • 举报
回复
mark下
uhlanme 2006-11-20
  • 打赏
  • 举报
回复
接分,看
suker0202 2006-11-20
  • 打赏
  • 举报
回复
好贴,自己学的时候,都记不轻看了多少编了
每接触一段时间又忘了 哎 惭愧呀!!!!!!!!!111
AFIC 2006-11-20
  • 打赏
  • 举报
回复
好帖啊,看了下,,,接分
yuanhan530 2006-11-20
  • 打赏
  • 举报
回复
好帖啊,看了下,,,接分
guileen 2006-11-19
  • 打赏
  • 举报
回复
楼主我支持你,接分
tianchai12321 2006-11-01
  • 打赏
  • 举报
回复
又看了2遍书,再看你的,好象明白多了
LiChenYue 2006-11-01
  • 打赏
  • 举报
回复
接分!
lin_style 2006-10-31
  • 打赏
  • 举报
回复
哦。你把那个IF判断搞清楚就不会了
tianchai12321 2006-10-31
  • 打赏
  • 举报
回复
谢谢,看了2遍了,但还是有点晕
lin_style 2006-10-30
  • 打赏
  • 举报
回复
特此向 A_B_C_ABC(黄瓜◥ @^@◤业余爱好而已)道歉。
lin_style 2006-10-30
  • 打赏
  • 举报
回复
一时忘记,

特此补充


资料来源A_B_C_ABC(黄瓜◥ @^@◤业余爱好而已) http://blog.csdn.net/a_b_c_abc/archive/2005/11/25/536925.aspx

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧