本文将介绍字符串匹配算法中的 朴素算法、快速匹配和自动机匹配
(1)朴素算法
朴素算法是一个比较容易理解的算法,也是容易编写的算法。
设偏移量为s,当T【s+0,s+1..s+n-1】=P[0,1,...n-1]时,说明文本中匹配到查找字符串,下图为匹配示意图。
朴素匹配c语言实现: http://shaojiashuai123456.iteye.com/blog/1637823
(2)快速匹配
快速匹配算法通过使用额外的记录数组,记录模式串P匹配失败时的跳转位置,从而实现匹配失败时的快速跳转,从而减少重复匹配。
如上图所示,由模式串P得出失败跳转位置数组。
KMP算法c语言实现: http://shaojiashuai123456.iteye.com/blog/1637804
(3)自动机匹配
自动机匹配通过预先对模式串P预处理,建立状态转换图,从而使输入串通过状态转换来匹配模式串P。
上图展示了模式串P状态转换的过程,下面将给出状态变迁函数伪代码:
Compute-Transition-Function(P, ∑)
{
m = length[P];
for q=0 to m
{
for each character A∈∑
{
k = min(m,q+1);
while(Pk is not a prefix of PqA)
k--;
δ(q,a)=k;
}
}
}
第一个for循环代表构造第q个状态
第二个for循环代表放入一个字符
第三个while循环用来计算下一个状态
举例说明其过程:
例如模式串P = ababaca ,当q=5时(第一个for),输入字符为a(第二个for)时,此时 PqA = ababaa ,此时 m=7 ,q=5, k=min(7,5+1) = 6;
现在进入while循环:
Pk(k=6) = ababac , 与 PqA(ababaa)后缀比较,不相等,则k-- ,
Pk(k=5) = ababa , 与 PqA(ababaa)后缀比较,不相等,则k-- ,
Pk(k=4) = abab , 与 PqA(ababaa)后缀比较,不相等,则k-- ,
Pk(k=3) = aba , 与 PqA(ababaa)后缀比较,不相等,则k-- ,
Pk(k=2) = ab , 与 PqA(ababaa)后缀比较,不相等,则k-- ,
Pk(k=1) = a , 与 PqA(ababaa)后缀比较,相等,返回k (k=1)
这回应该知道状态转换表是怎么形成的吧,其实其效率不是很高,因为可以发现其形成过程中使用了太多的循环,因此其匹配效率远不如KMP算法,但是其变形 AC自动机 却是多模匹配的最牛匹配算法,AC自动机通过使用trie树与KMP思想结合,有兴趣的可以自己学习下。