美文网首页
模式匹配算法

模式匹配算法

作者: lx_jian | 来源:发表于2019-08-13 18:10 被阅读0次

1. 模式匹配

模式匹配是数据结构中字符串的一种基本运算,给定一个子串,要求在某个字符串中找出与该子串相同的所有子串,这就是模式匹配。

假设P是给定的子串,T是待查找的字符串,要求从T中找出与P相同的所有子串,这个问题成为模式匹配问题。P称为模式,T称为目标。如果T中存在一个或多个模式为P的子串,就给出该子串在T中的位置,称为匹配成功;否则匹配失败。

2. 常见模式匹配算法

2.1 朴素的模式匹配算法

假设我们要从主串s="goodgoogle"找到t="google"这个子串的位置,我们需要下列步骤:

(1)主串s的第1位开始,s与t前三个字符都匹配成功,第四个字符不匹配(竖线表示相等,闪电状弯折表示不想等).

(2)主串s的第2位开始,匹配失败

(3)主串s的第3位开始,匹配失败

(4)主串s的第4位开始,匹配失败

(5)主串s的第5位开始,s与t,6个字符全部匹配成功

对主串s的每一个字符作子串t开头,要与匹配的字符串t进行匹配。对主串s作大循环,每一个字符开头作t长度的小循环,直到匹配成功或者全部遍历完为止。

图1

时间复杂度:

最好情况:如"googlegood"中找"google",第一个开始位置就匹配,时间复杂度为O(1).

其次:比如"abcdefgoogle"中找"google",时间复杂度O(n+m),其中n为主串长度,m为子串长度,根据等概率原则,平均(n+m)次查找,时间复杂度为O(n+m)

最坏的情况,每次不成功都发生在串t的最后一个字符,比如子串t="0000000001",9个"0"和一个"1",主串s="00000000000000000000000000000000000000000000000001",49个"0"和一个"1"时间复杂度为O((n-m+1)*m)

2.2 KMP匹配算法

(1)假设主串s="abcdefgab",t="abcdex"。"abcdex"的首字符"a"与后面的串"bcdex"中任何一个字符都不相等,子串t与主串s的前5个字符分别相等,意味着子串t的首字符"a"不可能与s串的第2位到第5位的字符相等。

图2

(2)假设s="abcababca",t="abcabx"。子串t中有重复字符。第一步,前5个字符相等,第6个字符不相等,根据前面的经验,t的首字符"a"与t中第二位、第三位字符均不等,不需要判断。子串t中第1位与第4位相等,第2位与第5位相等;主串s中第4位,第5位分别与子串t中第4位,第5位相等,意味着子串的第1位与第2位分别与主串第4位与第5位相等,不需要判断。

图3

总结:i值不回溯,j值的变化只与子串有关,取决于t串中的结构中是否有重复的字符串。我们把t串各个位置的变化定义为一个数组next,next的长度就是t串的长度。

图4 图5

时间复杂度:对于get_next来说,t的长度为m,由于只涉及到简单循环,其时间复杂度为O(m);i的值不回溯,主串的长度为n,while循环的时间复杂度为O(n),因此整个代码的数减复杂度为O(n+m)

(3)KMP模式匹配算法改进

KMP匹配算法还是有缺陷的,比如子串s="aaaabcde",子串t="aaaaax",子串t的next为012345.

图6

我们发现②③④⑤步骤是多余的。由于子串t中第2、3、4、5个位置上的字符串和守卫上的字符串相等,那么可以用首位next[1]来代替后续与它相等的字符后续的next[j],由于子串t中第2、3、4、5个位置上的字符串和首位上的字符串相等,那么可以用首位next[1]来代替后续与它相等的字符后续的next[j]。

2.3 BM匹配算法

Boyer-Moore(BM)算法是一种基于后缀匹配的模式串匹配算法,后缀匹配就是模式串从右到左开始比较,但模式串的移动还是从左到右的。字符串匹配的关键就是模式串的如何移动才是最高效的,Boyer-Moore为了做到这点定义了两个规则:坏字符规则和好后缀规则,下面图解给出定义:

图7

2.3.1 坏字符规则

(1)如果坏字符没有出现在模式字符中,则直接将模式串移动到坏字符的下一个字符:

图8(坏字符c,没有出现模式串P中,直接将P移动c的下一个位置)

(2)如果坏字符出现在模式串中,则将模式串最靠近好后缀的坏字符(当然这个实现就有点繁琐)与母串的坏字符对齐:

图9(如果模式串P是babababab,则是将第二个b与母串的b对齐)

2.3.2 好后缀规则

好后缀规则分三种情况:

(1)模式串中有子串匹配上好后缀,此时移动模式串,让该子串和好后缀对齐即可,如果超过一个子串匹配上好后缀,则选择最靠靠近好后缀的子串对齐。

图10

(2)模式串中没有子串匹配上后后缀,此时需要寻找模式串的一个最长前缀,并让该前缀等于好后缀的后缀,寻找到该前缀后,让该前缀和好后缀对齐即可.

图11

其实,1和2都可以看成模式串还含有好后缀串(好后缀子串也是好后缀).

(3)模式串中没有子串匹配上后后缀,并且在模式串中找不到最长前缀,让该前缀等于好后缀的后缀。此时,直接移动模式到好后缀的下一个字符。

图12

2.4 AC多模式算法

Aho-Corasick算法又叫AC自动机算法,是一种多模式匹配算法。Aho-Corasick算法可以在目标串查找多个模式串,出现次数以及出现的位置。

2.4.1 Aho-Corasick算法原理

Aho-Corasick算法主要是应用有限自动机的状态转移来模拟字符的比较,下面对有限状态机做几点说明:

图13

上图是由多模式串{he,she,his,hers}构成的一个有限状态机:

1.该状态当字符匹配是按实线标注的状态进行转换,当所有实线路径都不满足(即下一个字符都不匹配时)按虚线状态进行转换。

2.对ushers匹配过程如下图所示:

图14

当转移到红色结点时表示已经匹配并且获得模式串

2.4.2 Aho-Corasick算法步骤

Aho-Corasick算法和前面的算法一样都要对模式串进行预处理,预处理主要包括字典树Tire的构造,构建状态转移表(goto),失效函数(failure function),输出表(Output)。

Aho-Corasick算法包括以下3个步骤

                1.构建字典树Tire

                2.构建状态转移表,失效函数(failure function),输出表(Output)

                3.搜索路径(进行匹配)

下面3个步骤分别进行介绍

构建字典树Tire

        Tire是哈希树的变种,Tire树的边是模式串的字符,结点就是Tire的状态表,下图是多模式串{he,she,his,hers}的Tire树结构:

图15

构建goto函数、failure function和Output函数     

         goto函数(状态转移函数):goto(pre,v)=next,完成这样的任务:在当前状态pre,输入字符v,得到下一个状态next,如果没有下个状态则next=failure。 

图16

     failure function:失效函数是处理当前状态是failure时的处理。 

图17

    output函数:当完成匹配是根据状态输出匹配的模式串。

图18

多模式串{he,she,his,hers}最终的有限状态机图:

3. 模式匹配算法的本质

扫描+特征比较

扫描:

        1、逐位扫描;

        2、边界特征扫描;

特征提取:核心是目标特征分析

        1、整体特征:整体hash;

        2、边界特征:忽略中间量,仅对首尾做特征提取;

        3、分析特征:适合有重复字符的匹配模式;

        4、统配特征:边界特征+限制特征+位数;

相关文章

  • 字符串的模式匹配(BF算法与KMF算法)

    串的模式匹配 1.朴素的模式匹配(Brute-Force)算法 Brute-Force算法的实现: 测试程序以及运...

  • 一些有关算法的

    字符串模式匹配算法 字符串的KMP算法详解部分匹配表(即)向右移一位就可以得到next数组。字符串模式匹配算法 R...

  • 6.4 字符串模式匹配

    1. 朴素模式匹配算法(又叫 简单模式匹配算法) 基本思路:暴力匹配,从第一个字符开始,挨个匹配,如果不符合,则从...

  • 5.字符串--大话数据结构

    定义 是由零个或多个字符组成的有限序列 Index的实现算法 朴素的模式匹配算法 KMP模式匹配算法 next[j...

  • 大话数据结构—串(九)

    1.朴素的模式匹配算法

  • KMP算法讲解

    KMP 算法 : 模式匹配算法 主要应用于 字符串的匹配。9月21日更新

  • KMP算法理解

    KMP的由来 在KMP算法之前,对文本进行匹配时使用的是朴素模式匹配算法,也就是最简单匹配算法.当然运行效率也是让...

  • 字符串匹配算法总结

    字符串匹配算法总结 所有代码集合 在一个主串中匹配模式串 BF算法   最简单的使用strcmp逐个匹配的算法, ...

  • 模式匹配算法

    《数据结构(C语言版)》上给出了两种模式匹配算法,BF算法和KMP算法。 存在一个主串S和一个模式T,要在主串S中...

  • 模式匹配算法

    1. 模式匹配 模式匹配是数据结构中字符串的一种基本运算,给定一个子串,要求在某个字符串中找出与该子串相同的所有子...

网友评论

      本文标题:模式匹配算法

      本文链接:https://www.haomeiwen.com/subject/eqpkkctx.html