字符串匹配算法总结

  • 格式:docx
  • 大小:29.45 KB
  • 文档页数:11

下载文档原格式

  / 26
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Brute Force(BF或蛮力搜索) 算法:

这是世界上最简单的算法了。

首先将匹配串和模式串左对齐,然后从左向右一个一个进行比较,如果不成功则模式串向右移动一个单位。

速度最慢。

那么,怎么改进呢?

我们注意到Brute Force 算法是每次移动一个单位,一个一个单位移动显然太慢,是不是可以找到一些办法,让每次能够让模式串多移动一些位置呢?

当然是可以的。

我们也注意到,Brute Force 是很不intelligent 的,每次匹配不成功的时候,前面匹配成功的信息都被当作废物丢弃了,当然,就如现在的变废为宝一样,我们也同样可以将前面匹配成功的信息利用起来,极大地减少计算机的处理时间,节省成本。^_^

注意,蛮力搜索算法虽然速度慢,但其很通用,文章最后会有一些更多的关于蛮力搜索的信息。

KMP算法

首先介绍的就是KMP 算法。

这个算法实在是太有名了,大学上的算法课程除了最笨的Brute Force 算法,然后就介绍了KMP 算法。也难怪,呵呵。谁让Knuth D.E. 这么world famous 呢,不仅拿了图灵奖,而且还写出了计算机界的Bible ( 业内人士一般简称TAOCP). 稍稍提一下,有个叫H.A.Simon 的家伙,不仅拿了Turing Award ,顺手拿了个Nobel Economics Award ,做了AI 的爸爸,还是Chicago Univ 的Politics PhD ,可谓全才。

KMP 的思想是这样的:

利用不匹配字符的前面那一段字符的最长前后缀来尽可能地跳过最大的距离

比如

模式串ababac 这个时候我们发现在c 处不匹配,然后我们看c 前面那串字符串的最大相等前后缀,然后再来移动

下面的两个都是模式串,没有写出来匹配串

原始位置ababa c

移动之后aba bac

因为后缀是已经匹配了的,而前缀和后缀是相等的,所以直接把前缀移动到原来后缀处,再从原来的c 处,也就是现在的第二个b 处进行比较。这就是KMP 。

Horspool 算法。

当然,有市场就有竞争,字符串匹配这么大一个市场,不可能让BF 和KMP 全部占了,于是又出现了几个强劲的对手。

第一个登场的是

Horspool 算法的思想很简单的。不过有个创新之处就是模式串是从右向左进行比较的。很好很强大,为后来的算法影响很大。

匹配串:abcbc sdxzcxx

模式串:cbcac

这个时候我们从右向左进行对暗号,c-c ,恩对上了,第二个b-a ,不对啊,我们应该怎么办?难道就这么放弃么。于是,模式串从不匹配的那个字符开始从右向左寻找匹配串中不匹配的字符b 的位置,结果发现居然有,赶快对上赶快对上,别耽误了。

匹配串:abcbcsd xzcxx

模式串:cbcac

然后继续从最右边的字符从右向左进行比较。这时候,我们发现了,d-c 不匹配啊,而且模式穿里面没有噢,没办法,只好移动一个模式串长度的单位了。

匹配串:abcbcsdxzcxx

模式串:cbcac

Boyer-Moore算法

是一个很复杂的算法,当然,虽然理论上时间复杂度和KMP 差不多,但是实际上却比KMP 快数倍,可见实践是检验真理的唯一标准。

分为两步预处理,第一个是bad-character heuristics ,也就是当出现错误匹配的时候,移位,基本上就是做的Horspool 那一套。

第二个就是good-suffix heuristics ,当出现错误匹配的时候,我还要从不匹配点向左看啊,以前匹配的那段子字符串是不是在模式串本身中还有重复的啊,有重复的话,那么我就直接把重复的那段和匹配串中已经匹配的那一段对齐就是了。再比较

匹配串:abaccba bbazz

模式串:cbadcba

我们看到已经匹配好了cba ,但是c-d 不匹配,这个时候我们发现既可以采用bad-character heuristics ,也可以使用good-suffix heuristics( 模式串:cba dcba ) ,在这种情况下,邪不压正。毅然投奔good 。移动得到

匹配串:abaccbabbaz z

模式串:cbadcba

可是,我们有时候也发现,已经匹配好的那一部分其实并没有再有重复了的啊。这个时候,我们发现已经匹配好的那串字符串有一部分在开头重新出现了,那么,赶快,对齐吧。

匹配串:abacccb bbazz

模式串:cbadccb

然后得到

匹配串:abacccbbbazz

模式串:cbadccb

当两种Good-Suffix 出现的时候,取移动距离最大的那个。

Sunday算法

最后一个是Sunday 算法,实际上比Boyer-Moore 还快,呵呵。长江后浪推前浪。

看原始论文的题目,D.M. Sunday 貌似是故意想气气Boyer-Moore 两位大牛似的。呵呵。不过实际上的确Sunday 算法的确比BM 算法要快,而且更简单。

Sunday 的算法思想和Horspool 有些相似,但是。当出现不匹配的时候,却不是去找匹配串中不匹配的字符在模式串的位置,而是直接找最右边对齐的右一位的那个字符在模式串的位置。

比如:

匹配串:abcbc zdxzc

模式串:zbcac

恩,这里我们看到b-a 没有对上,我们就看匹配串中的z 在模式串的位置,然后,嘿嘿。

匹配串:abcbczdxzc

模式串:zbcac

如果模式串中的没有那个字符怎么办呢?很简单,跳过去呗。

匹配串:abcbc edxzcs

模式串:zbcac

e 不在模式串中出现

那么我们就

匹配串:abcbcedxzcs