字符串匹配算法

来源:互联网 发布:怎么使用erp软件 编辑:程序博客网 时间:2024/04/30 06:50

最近看了一些匹配算法,发现其实算法也不是很高深,也还是要一个个匹配字符嘛,就是在一个个匹配基础上想一些法子提升性能和优化。

下面列出一些常用匹配算法:


图1 字符串常用匹配算法

单模式匹配是指一次操作只能判断待匹配序列是否和某一个模式匹配。

多模式匹配是指一次操作能判断待匹配序列是否和多个模式匹配。

单模式匹配:

KMP算法
具体参看wiki的链接:http://zh.wikipedia.org/wiki/%E5%85%8B%E5%8A%AA%E6%96%AF-%E8%8E%AB%E9%87%8C%E6%96%AF-%E6%99%AE%E6%8B%89%E7%89%B9%E7%AE%97%E6%B3%95
我这里写下我的感悟:
KMP的关键就是覆盖函数,覆盖函数的一个思想是先计算出每个字符的覆盖值。(我自己实现这个算法时,尝试的是每次匹配失败再调用覆盖函数计算覆盖值的方法,这样必会产生大量多余的计算。)
覆盖函数所表征的是pattern本身的性质,可以让为其表征的是pattern从左开始的所有连续子串的自我覆盖程度。
比如对于序列
a0a1...aj-1 aj
要找到一个k,使它满足
a0a1...ak-1ak=aj-kaj-k+1...aj-1aj
比如如下的字串,abaabcaba

由于计数是从0始的,因此覆盖函数的值为0说明有1个匹配,对于从0还是从来开始计数是偏好问题,具体请自行调整,其中-1表示没有覆盖。
使pattern前k字符与后k字符相匹配,k要尽可能的大(原因是如果有比较大的k存在,而我们选择较小的满足条件的k,那么当失配时,我们就会使pattern向右移动的位置变大,而较少的移动位置是存在匹配的,这样我们就会把可能匹配的结果丢失。)
比如下面的序列,

在红色部分失配,正确的结果是k=1的情况,把pattern右移4位,如果选择k=0,右移5位则会产生错误。
计算这个overlay函数的方法可以采用递推,可以想象如果对于pattern的前j个字符,如果覆盖函数值为k

a0a1...ak-1ak=aj-kaj-k+1...aj-1aj
则对于pattern的前j+1序列字符,则有如下可能
⑴     pattern[k+1]==pattern[j+1] 此时overlay(j+1)=k+1=overlay(j)+1
⑵     pattern[k+1]≠pattern[j+1] 此时只能在pattern前k+1个子符组所的子串中找到相应的overlay函数,h=overlay(k),如果此时pattern[h+1]==pattern[j+1],则overlay(j+1)=h+1否则重复(2)过程.

匹配过程

当发生在j长度失配时,只要把pattern向右移动j-overlay(j)长度就可以了。

BM算法
具体请参看wiki:http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm
BM中关键的两个规则:坏字符规则” “好后缀规则


Horspool算法

具体参看wiki:http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore%E2%80%93Horspool_algorithm

首先,要构造失配时模式串中元素的移动距离数组d。即某个

Sunday算法

百度百科中很详细了:http://baike.baidu.com/view/6325831.htm

注意点:失配后用的是目标串中参加过匹配的最末位字符的下一位,而不是适配字符的下一位。

使用Sunday算法不需要固定地从左到右匹配或者从右到左的匹配(这是因为失配之后我们用的是目标串中后一个没有匹配过的字符),我们可以对模式串中的字符出现的概率事先进行统计,每次都使用概率最小的字符所在的位置来进行比较,这样失配的概率会比较大,所以可以减少比较次数,加快匹配速度。
如下面的例子:
目标串:abcdefghijk
模式串:aabcc
模式串中b只出现了一次,a,c都出现了2次,所以我们可以先比较b所在的位置(只看模式串中的字符的话,b失配的概率会比较大)

http://blog.csdn.net/WINCOL/article/details/4795369
Horspool参考:http://blog.csdn.net/ljsspace/article/details/6554555
BM参考:http://blog.csdn.net/iJuliet/article/details/4200771
KMP参考:http://blog.csdn.net/v_JULY_v/article/details/6111565


原创粉丝点击