字符串匹配算法

作者: 橙小汁 | 来源:发表于2016-07-08 08:10 被阅读311次

1、BF算法

假设现有一字符串,“BBC ABCDAB ABCDABCDABDE”将其称为给定串,相应有一匹配串“ABCDABD”。

两个串的第一个字母先相互比较:

图1

可得第一个字符不相同,则继续向后比较,直到比较到第一个字符相同,如下图:

图2

然后继续比较,直到发现给定串中的字符与匹配串中的不同,这时BF算法的思想是将匹配串与给定串的当前位置的下一位进行比较,这会导致很多重复比较,时间复杂度到达O(n*m),n代表给定串的长度,m代表匹配串的长度。

2、KMP算法

此种算法,后面需要用到部分匹配表,所以先讲一下部分匹配表。我们都知道前缀就是一个字符串中除了最后一个字符之外的所有字符组合,后缀是一个字符串中除了第一个字符之外的所有字符的组合。

以匹配串“ABCDABD”为例,"A"的前缀和后缀都为空集,共有元素的长度为0; "AB"的前缀为[A],后缀为[B],共有元素的长度为0;"ABC"的前缀为[A, AB],后缀为[BC, C],共有元素的长度0;"ABCD"的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0;"ABCDA"的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为"A",长度为1;"ABCDAB"的前缀为[A, AB, ABC, ABCD,ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为"AB",长度为2;"ABCDABD"的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0。因此,可以得到匹配串的部分匹配表:

图3

此种算法前半部分和BF算法一样,都是从第一个字符开始比较,然直到找到与匹配串第一个字符相匹配的位置,然后再继续比较,直到与给定串不匹配,此时,KMP的做法是通过部分匹配表来进行移位,有公式:移动位数 = 已匹配的字符数 - 对应的部分匹配值(已匹配字符的最后一个字符)。

图4

以到达此步为例:已匹配的字符数为6,B的部分匹配值为2,所以移动6-2=4位,到如下:

图5

此时移动2-0=2位,到如下:

图6

此时移动1位,到如下:

图7

此时移动6-2=4位,到如下:

图8

达到完美匹配,此时如果还想找出字符串的全部匹配串,则移动7-0=7位。

时间复杂度是O(n+m)。

3、Boyer-Moore算法

(暂且不管坏字符和好后缀的定义,后文介绍)

坏字符规则:移动为数 = 坏字符的位置 - 匹配串中上一次出现的位置(若坏字符不出现在匹配串中,则上一次出现位置为-1)

好后缀规则:移动为数 = 好后缀的位置(以好后缀最后一个位置为准) - 匹配串中上一次出现的位置(若好后缀在匹配串中不重复出现,则上一次出现位置为-1)

假设现有一字符串,“HERE IS A SIMPLE EXAMPLE”将其称为给定串,相应有一匹配串“EXAMPLE”。

图9

先从尾部开始比较,可以看到S与E不匹配,则将S称为坏字符,此时用坏字符规则,则移动为数为6-(-1)=7位,得到如下:

图10

此时用坏字符规则,则移动为数为6 - 4=2位,得到如下:

图11

此时的MPLE,PLE,LE,E都称为好后缀,此时用好后缀规则,则移动为数为6 - 0 = 6位,得到:

图12

此时用坏字符规则,则移动为数为6 - 4 = 2位,得到:

图13

此时达到完美匹配,如果还想找出字符串的全部匹配串,则移动6-0=6位。

end。

相关文章

  • 字符串匹配

    indexOf 底层就是使用字符串匹配算法 字符串匹配算法很多 BF( Brute Force)算法 暴力匹配算...

  • KMP字符串匹配算法

    KMP字符串匹配算法 先总结一下之前的几种字符串匹配算法 1 BF算法, 最简单的字符串匹配算法, 可以直接使用s...

  • KMP算法文章合集

    字符串的查找:朴素查找算法和KMP算法 暴力匹配算法与KMP算法(串的匹配) 字符串查找算法BF和KMP 字符串匹...

  • 一些有关算法的

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

  • 字符串匹配算法

    场景:字符串A为主串,字符串B为模式串,比较字符串B是否能够在字符串A中进行匹配? 匹配算法:BF算法和RK算法。...

  • 字符串匹配算法

    以下为学习 《数据结构与算法之美 -- 字符串匹配》 的记录。 BF算法 即暴力匹配算法,循环遍历匹配。 RK算法...

  • 2022-01-25

    1.字符串匹配BM算法 在文本中查找字符串匹配算法,坏字符串规则和好后缀规则坏字符串规则: 从后往前匹配,第一个不...

  • 20-字符串匹配

    字符串匹配 这章节,我们会讲到几大典型的字符串匹配算法 BF算法 BF算法是最最符合正常人逻辑思维的一种匹配模式,...

  • leetcode字符串匹配算法之KMP算法

    本篇介绍一种高效的字符串匹配算法——KMP算法。 KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J....

  • 中文分词的方法

    1、基于字符串匹配的方法 1.1 正向最大匹配分词算法1.2 逆向最大匹配分词算法1.3 双向最大匹配分词算法1....

网友评论

  • 薄炳鑫:了解算法
  • LuoQ:从图7到图8的移动中貌似D下面的数字应该是2,如果是这样图3中的红色数字(部分匹配表?)就好理解了,否则真不知道怎么得出的
    橙小汁:@LuoQ 感谢你的热心提醒,文章已经更新了。谢谢指出。
    LuoQ:@bingdao  我觉得加上部分匹配值的解释非常有必要,对于没接触过这块知识的人来说。 
    - "A"的前缀和后缀都为空集,共有元素的长度为0;
      - "AB"的前缀为[A],后缀为[B],共有元素的长度为0;
      - "ABC"的前缀为[A, AB],后缀为[BC, C],共有元素的长度0;
      - "ABCD"的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0;
      - "ABCDA"的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为"A",长度为1;
      - "ABCDAB"的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为"AB",长度为2;
      - "ABCDABD"的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0。
    橙小汁:@LuoQ 你可能被图7中的红框误导了。图7中的匹配数字是6,已匹配的最后一位字符是B,B的部分匹配值是2,所以移动6-2=4位。

本文标题:字符串匹配算法

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