实现串匹配的并行算法_字符串匹配 ---- BM 算法原理

关于字符串匹配有很多算法, BF, BK, KMP, 但这些都不是这篇文章的重点. 文章的重点是另外一种更高效的算法 Boyer-Moore 算法, 一般文本编辑器中的查找功能都是基于它实现的.

前置内容

什么是字符串匹配? 它只不过是在一堆字符串中查找特定的字符串的行为, 就像下面的例子一样.

现在为了方便起见, 我们把一堆的字符串称为主串 main, 特定的字符串称为模式串 pattern, 查找过程就可以理解为不断移动 pattern 的过程. 我们从主串的第一个字符开始, 逐个匹配, 遇到不匹配的字符, 就将 pattern 移动一位,直到全部匹配上.

3e658e03c66a5f683f7c8aefb4866687.png

所以到这里, 我们就可以说, 更高效的字符串匹配就是更高效的模式串 pattern 移动. 如何进行高效的移动就是算法的意义所在.

暴力匹配

如果我们用一般方法来完成字符串匹配, 我们可以用一个循环来完成. 试着想象, 我们把模式串抽象的想象为一个字符, 同样的主串中的所有子串我也都抽象的想象为一个字符, 这个过程就变为了对一个字符的匹配, 代码就可以写成下面这样:

function search(main, pattern) {
    if (main.length === 0 || pattern.length === 0 || main.length < pattern.length) {
        return -1
    }
    for (let i = 0; i <= main.length - pattern.length; i++) {
        let subStr = main.slice(i, i + pattern.length) // 此处可以想象为一个字符
        if (subStr === pattern) {
            return i
        }
    }
    return -1;
}

这个方法简单粗暴, 所以有个名副其实的称呼叫做暴力匹配算法.

虽然我们上面把主串的子串, 和模式串都抽象为一个字符, 但实际比较时, 我们还是需要另一个循环来比较每个字符. 于是有人想了个改进的方法, 对主串中的子串和模式串进行哈希, 这样就每次比较哈希值就可以了. 但是这种方法, 治标不治本, 并没有提高移动模式串的效率.

坏字符匹配

现在我们来说另外一种匹配方法, 倒着匹配.

为什么要倒着匹配? 仔细的想一下我们在正方向匹配的时候, 遇到不匹配的字符我们能做什么?我们可以将字符一位一位的移动进行暴力匹配, 也可以拿主串中不匹配的字符在模式串中找到相等的字符, 然后移动该字符到主串中对应的位置, 如下图.

256de5316ac54d0eb6de7689d403952f.png

原本我们是正着过来的, 但现在却需要返回去, 那为什么不从一开始我们就倒着进行匹配? 我们从模式串的末尾倒着匹配, 当发现主串中无法匹配的字符时, 我们就把这个字符称为坏字符.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值