(未完)字符串模式匹配的几个方法

来源:互联网 发布:360沙盒软件 编辑:程序博客网 时间:2024/06/05 21:59

参考资料:

模式匹配的Brute-Force算法和KMP算法 

Matrix67博客--KMP算法详解


一、Brute-Force算法

      Brute-Force算法(BF,简单模式匹配算法)的基本思想就是:

  •  从主串s=”S0S1…Sn-1”的第一个字符开始和模式串P=”P0P1…Pn-1”的第一个字符比较;
  • 若相等,则继续比较后续字符;
  • 若不等,从主串s的第二个字符开始重新与模式串t的第一个字符比较;
  • 如此不断继续,若存在模式串中的每个字符依次和主串中的一个连续字符序列相等,则匹配成功,返回模式串 P 的第一个字符在主串中的下标;
  • 否则匹配失败,返回-1。

    范例如下:
               

算法效率:

       易知BF算法的时间复杂度是O(m*n).  慢的原因主要是:记一次比较时目标串S开始的位置为K,然后模式串P在和目标串S匹配到中途失效的时候,模式串P需要重新指向串开始的位置,更严重的是目标串要回退到K+1的位置。----简而言之,就是虽然模式串和目标串中途匹配了很多字符,直到遇到某个字符失败,而在重新开始比较时,目标串比较的起始位置需要回退,回退后且只比前一次比较移动了一个位置。显然,中途匹配的都是无用功。假定目标串S不动,模式串P在平行于目标串移动,这次失败让模式串S相对于目标串P只向右移动了一个位置。

           然后有时明明知道移动一个位置,也不可能产生正确的结果-----聪明的移动方法(KMP)是,匹配失效时,利用已知信息,让模式串S相对于主串P能有尽可能多的向右移动,或者是匹配失败时,主串指针尽可能少的回退。最坏的情况就是回退到上一次开始的位置的下一个(BF方法)。如下所示:


二、KMP算法

       KMP算法(Knuth-Morris-Pratt) 就是前面所说的移动时的”聪明“方法,前提是要求一些已知信息 ---- 这就是KMP算法中最重要:对模式串P所构建的 Shift 表。 基本算法思想是:

  • 设S为主串,P为模式串,设i 为主串S当前比较字符的下标,j 为模式串P当前比较字符的下标,另i和j的初值为0;
  • 当Si= Pj时,i和j分别增1再继续比较;
  • 否则i不变,j 改变为等于next [j] ,再继续比较。
  • 依次类推,直到下列两种情况之一:一种是j退回到某个j = next[j] 时有si = tj;则i和j分别增1再继续比较;另一种是j退回到j = -1,此时令主串和模式串的下标各增1(此时模式串下标便退回0:j = j + 1 = -1 + 1 = 0),再继续比较。

KMP算法在Matrix67的博客中讲的非常详细,其博客中总结的一句话是:扫描主串S,并更新可以匹配到模式串P的什么位置 ----其伪代码中的字符串下标是从1开始计数


算法的关键:next[]数组的确定

     这个过程就是前面说的,对模式串P所构建的 Shift 表,该过程只和模式串有关。因而可认为:KMP算法适用于,给定一个模式串P和一群不同的主串{S},问模式串P是哪些主串S的子串。
    这个过程也可以理解为对模式串P的 自匹配过程。重要的思想就是:对模式串P的某个字符 j,找到其前面的字符串P1 P2...Pj-1中 Max { 缀长度 | 前缀==后缀} ,该值就是next[j]的值。具体可定义如下(模式串下标从0开始计算,t 即为P)

               ①next[j]= max{ k | 0<k<j 且“t0t1…tk-1” = “tj-ktj-k+1…tj-1”}     当此集合非空时

               ②next[j]= 0                                         其他情况

               ③next[j]= -1                                        当 j = 0 时


        综上,KMP算法的过程分为两步:第一个是对模式串P做预处理,根据模式串本身的性质,从寻找前串中的最大 前缀==后缀长度,定义出next[] 数组;第二个是将模式串P和主串S去比较,当比较到模式串中某个字符j 和主串中字符i 不相等的时候,将j重新置为next[j],再和主串中的i比较 ----- 这样就保证了,主串指针i 没有回退的情况。


三、Boyer-Moore算法

      BM算法也是适用于单模式快速匹配的方法,算法的性能是:

  • BM算法比KMP算法要快;
  • 当模式中重复的部分很好时,BM算法效率高(类似KMP)
  • 需要比较的字符串数比输入字符串的长度(主串长度)n要小的多 --- KMP算法是主串每个字符都要比较

具体算法过程待补充


四、WM算法--适用于多模式匹配的算法

         主要是涉及到了三个表--Shift表、Pointer表、Prefix表

具体算法待补充



0 0
原创粉丝点击