- 3
- 0
- 约8.02千字
- 约 12页
- 2021-01-08 发布于天津
- 举报
字符串匹配那些事(一)
来源:搜索技术博客—淘宝 发布时间:2011-09-25 16:47 阅读:2146 次 推荐:0 原文链接 [收藏]
/page/107856/
摘要:本系列文章主要介绍几种常用的字符串比较算法,包括但不限于蛮力匹配算法, KMP算法,
BM算法,Horspool 算法,Sunday 算法,fastsearch 算法,KR算法等等。
本文主要介绍KMP算法和BM算法,它们分别是前缀匹配和后缀匹配的经典算法。所谓前缀 匹配是指:模式串和母串的比较从左到右,模式串的移动也是从左到右;所谓后缀匹配是指:模式 串和母串的的比较从右到左,模式串的移动从左到右。看得出来前缀匹配和后缀匹配的区别就仅仅 在于比较的顺序不同。下文分别从最简单的前缀蛮力匹配算法和后缀蛮力匹配算法入手,详细的介 绍KMP算法和BM算法以及它们的实现。
KMP算法
首先来看一下前缀蛮力匹配算法的代码 (以下代码从linux源码string.h 中抠出),模式串和
母串的比较是从左到右进行(strncmp()),如果找不到和模式串相同的子串,则从左到右移动模 式串,距离为1 ( s++ )。
har * strstr(register const char *s, register constchar *wanted)
{
register const size_t len = strlen(wanted);
if (len == 0) return ( char *)s;
while (*s !=* wanted || strncmp(s, wanted, len))
if (*s++== \0)
return ( char *)NULL;
return ( char *)s;
}
KMP算法中的KMP分别是指三个人名: Knuth、Morris、Pratt,其本质也是前缀匹配算法, 对比前缀蛮力匹配算法,区别在于它会动态调整每次模式串的移动距离,而不仅仅是加一,从而加 快匹配过程。下图通过一个直观的例子展示前缀蛮力匹配算法和 KMP算法的区别,前文提过,这
二者唯一的不同在于模式串移动距离。
文本爭T
a
b
a
b
a
b a
a E
a
b
j
橙式串P
a
b
a
b
a
c
b
a
b
3
b
3
c
b
前題力匚配算,一昌移动
k
a
b
a
t
a
c
b
KMP算? 禺移动
1,而
1,而KMP算法根据已经比较过
的前缀信息,了解到应该移动距离为 2 ;换句话说针对母串的下一个匹配字符, KMP算法了解它下
回应该匹配模式串的哪个位置,比如上图中,针对母串的第 i+1个字符,KMP算法了解它应该匹
配模式串的第k+1个字符。为什么会是这样,这是因为母串的子串 T[i-k, i]=aba ,而模式串的子
串P[O,k]=aba ,这二者正好相等。所以模式串应该移动到这个位置,从而让母串的第 i+1个字符
和模式串的第k+1个字符继续比较。
那k值又是如何寻找?请注意上图中, 模式串位置j已经匹配上母串的位置 i,也就是T[i-k, i]
=P[j-k, j]=aba ;根据前文的 T[i-k, i] = P[0, k] = aba ,从而得出 P[0, k] = P[j-k, j] = aba .
通过观察发现,就是在模式的子串 [0, j]中寻找一个最长前缀[0,k],从而使得[j-k, j] = [0,k] ;
于是可以定义一个jump数组,jump[j]=k ,表示满足P[0, k] ==P[j-k, j] 的最大k值,
或者表述为:如果模式串j+1匹配不上母串的i+1,那跳转到模式串k+1继续比较。有了这个jump 数组,就很容易写出 kmp算法的伪代码:
j:= 0;
for i:= 1 to n do
Begin
while (j 0) and (P[j+ 1 ]T[i]) do j:=jump[j];[
if P[j+ 1]=T[i] then j:=j+ 1;
if j=m then
Begin
writeln( Pattern occurs with shift ,i-m);
end;
end;
KMP算法中jump数组的构建可以通过归纳法来解决,首先确定 jump[1]=0 ;假设
jump[j]=k ,也就是 P[0, k] == P[j-k, k] ,如果 P[j+1] == P[k+1] ,那么得出[0,k+1] = P[j-k,
TOC \o 1-5 \h \z j+1],从而更加定义得出 jump[j+1] = k+1 ;
如果 P[j+1] != P[k+1] ,那就接着比较 P[j+1] ?= P[k1+1] ,其中(jump[k] = k1 ),根据
(jump[k]=k1 )的定
原创力文档

文档评论(0)