美文网首页
字符串匹配 BM

字符串匹配 BM

作者: _旁观者_ | 来源:发表于2019-01-22 17:50 被阅读0次

字符串HERE IS A SIMPLE EXAMPLE
搜索串 EXAMPLE

KMP中比较是从前向后比较,而在BM从后向前比较

在比较之前,先介绍两个概念

  • 坏字符 (字符串搜索串 对应不相同就是 坏字符
    坏字符.png
  • 好字符 (字符串搜索串 对应相同就是 好字符
好字符.png

坏字符串比较

有两种情况 (搜索串中是否包含坏字符

  • 搜索串包含坏字符时, 移动到相应的位置即可(如果多个的话,移动到最近的一个)
  • 搜索串不包含坏字符时, 移动整个搜索串,如图
    整个移动.png

好字符串比较 (同上面类似)

  • 搜索串不包含好字符,移动应该是这样
  • 搜索串部分包含好字符

好字符串只有E有对应的,移动到'' EXA '' 的E的位置

  • 搜索串整个包含好字符

在同时存在好字符和坏字符时,选择移动步数大的,如


此时选择好字符移动

整个移动规则
整个移动步骤.png

代码实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script>
        function BM (string, searchString) {
            this.string = string // 字符串
            this.searchString = searchString // 搜索词
            this.lengthOfSearchString = this.searchString.length
            this.badStringIndex = 0 //搜索词中的上一次出现位置
            this.indexSearchString = 0 // 坏字符的位置
            this.sameStringLength = 0 // 已匹配的字符数
            this.index = 0 // 匹配位置索引
        }
        BM.prototype.init = function () {
            this.search()
        }
        BM.prototype.search = function () {
            var _that = this
            if (_that.lengthOfSearchString < _that.string.length) {
                for (let i = _that.lengthOfSearchString - 1; i < _that.string.length; i++) {
                    for (var j = _that.lengthOfSearchString - 1; j >= 0; j--) {
                        // 由于要多次比较, 缓存一下
                        let tempString = _that.string[i-(_that.lengthOfSearchString - 1-j)]
                        // 匹配搜索词,不同的话根据好、坏字符计算移动步数,相同的话sameStringLength + 1
                        if (_that.searchString[j] !== tempString) {
                            if (j === this.lengthOfSearchString-1) {
                                console.log('坏字符规则')
                                i = _that.badStep(i, tempString, j)
                            }else {
                                console.log('比较好坏字符规则')
                                // 比较好坏字符规则,选出移动步数大的
                                i = Math.max(_that.badStep(i, tempString, j), _that.goodStep(i, tempString, j))
                            }
                            break
                        }else {
                            _that.sameStringLength++
                        }
                    }
                    // 判断是否全部匹配
                    if(_that.sameStringLength === _that.searchString.length) {
                        _that.index = i - _that.searchString.length +1
                        _that.sameStringLength = 0
                        break
                    }else {_that.sameStringLength = 0}
                }
            }
            if(_that.index) {
                alert('匹配位置索引为' + _that.index+ _that.string[_that.index])
            }else {
                alert('无匹配项')
            }
        }
        BM.prototype.badStep = function (i, tempString, j) { // 由坏字符计算移动步数
            this.badStringIndex = this.searchString.indexOf(tempString)
            this.indexSearchString = j
            return (i + (this.indexSearchString - this.badStringIndex) - 1)
        }
        BM.prototype.goodStep = function (i, tempString, j) { // 由好字符计算移动步数
            let arr = []
            let maxStep = {index: -1, stringIndex: -1}
            for (let m = j+1; m < this.lengthOfSearchString; m++) {
                let goodString = this.searchString.substr(m) // 好字符串
                let leftGoodString = this.searchString.substr(0,m) // 好字符串左侧的字符串
                let index = leftGoodString.indexOf(goodString)
                if (index > -1) {
                    arr.push({index: index, stringIndex: m})
                }
            }
            if (arr.length === 0) { // 没有匹配的字符串移动整个字符串
                return (i + this.lengthOfSearchString)
            }else { // 有匹配的字符串, 
                arr.forEach(item => {
                    if(item['stringIndex'] - item['index'] > maxStep['stringIndex'] - maxStep['index']) {
                        maxStep['index'] = item['index']
                        maxStep['stringIndex'] = item['stringIndex']
                    }
                })
                return (i + maxStep['stringIndex'] - maxStep['index'])
            }
        }
        let bm = new BM('HERE IS A SIMPLE EXAMPLE', 'EXAMPLE')
        bm.init()

    </script>
</body>
</html>

相关文章

  • 2022-01-25

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

  • 字符串匹配 BM

    字符串HERE IS A SIMPLE EXAMPLE搜索串 EXAMPLE。 在KMP中比较是从前向后比较,而在...

  • 进击算法:字符串匹配的 BM 算法

    进击算法:字符串匹配的 BM 算法 BM 算法介绍 各种文本编辑器的 "查找" 功能(Ctrl+F),大多采用 B...

  • 子字符串查找(1)

    一、定义 本文主要介绍子字符串查找的各类常用算法,如朴素匹配算法(暴力查找)、KMP算法、BM算法等。各类匹配算法...

  • 字符串匹配 - BM算法

    BM 算法是非常高效的匹配算法,据说他的执行效率比大名鼎鼎的 KMP 算法还要快很多。那么,BM 算法有什么过人之...

  • 字符串匹配算法(二)BM

    一、简介 此文介绍另一款更高效的字符串匹配算法,据称较 KMP 算法而言,效率提高了3~5倍。 该算法由 Bob ...

  • 字符串匹配之 BM 算法

    一、基本概念 字符串匹配是计算机科学领域中最古老、研究最广泛的问题之一,层出不穷的前辈们也总结了非常多经典的优秀算...

  • BM算法

    BM算法的效率是KMP算法的3-5倍,是一种效率高,构思巧妙的字符串匹配算法。 与基于前缀比较的暴力匹配算法以及K...

  • 学习BM算法的姿势

    BM算法简介 BM是字符串搜索算法。 字符串搜索单模式下有BF、RK、BM、KMP算法,其中BF是暴力搜索,RK是...

  • BM算法

    BM算法(Boyer-Moore)不仅效率高,而且构思巧妙,是十分有效的字符串匹配算法,比KMP算法要更加高效。 ...

网友评论

      本文标题:字符串匹配 BM

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