Boyer-Moore 字符串匹配算法

简介: Boyer-Moore 字符串匹配算法

博主介绍: ✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家✌

Java知识图谱点击链接:体系化学习Java(Java面试专题)

💕💕 感兴趣的同学可以收藏关注下不然下次找不到哟💕💕

1687957896446.jpg

1、什么是 Boyer-Moore

Boyer-Moore 是一种字符串匹配算法,用于在一个文本串中查找一个模式串的出现位置。该算法由 Robert S. Boyer 和 J Strother Moore 于 1977 年提出,是一种高效的字符串匹配算法之一。

Boyer-Moore 算法的核心思想是利用模式串中的字符出现规律来跳过尽可能多的比较操作,从而提高匹配的效率。它分为两个阶段:预处理阶段和匹配阶段。

在预处理阶段,算法会根据模式串的内容构建两个规则表:坏字符规则表和好后缀规则表。坏字符规则表记录了每个字符在模式串中最后一次出现的位置,用于确定坏字符的移动距离;好后缀规则表记录了模式串中每个后缀子串的匹配位置,用于确定好后缀的移动距离。

在匹配阶段,算法从文本串的开头开始与模式串进行匹配。当发现不匹配的字符时,根据坏字符规则表和好后缀规则表来确定模式串的移动距离,以尽可能地跳过不可能匹配的位置。通过不断地向后滑动模式串,直到找到匹配或完全不匹配为止。

Boyer-Moore 算法在处理大型文本串时具有较高的效率,尤其是在模式串较长且包含重复字符时。它的时间复杂度为 O(n/m),其中 n 是文本串的长度,m 是模式串的长度。

2、Boyer-Moore 的优缺点

Boyer-Moore 算法具有以下优点:

  1. 高效性:Boyer-Moore 算法在大多数情况下比其他字符串匹配算法更快。它利用了模式串中的字符出现规律,能够跳过尽可能多的比较操作,从而提高匹配的效率。

  2. 预处理快速:Boyer-Moore 算法在预处理阶段构建坏字符规则表和好后缀规则表的时间复杂度为 O(m),其中 m 是模式串的长度。这使得算法在匹配阶段能够快速定位模式串的移动距离。

  3. 适用性广泛:Boyer-Moore 算法适用于各种不同类型的模式串,包括长模式串和包含重复字符的模式串。它在处理大型文本串时表现出色。

Boyer-Moore 算法的缺点包括:

  1. 预处理空间消耗:Boyer-Moore 算法在预处理阶段需要构建坏字符规则表和好后缀规则表,这可能会消耗较多的额外空间,尤其是对于较长的模式串。

  2. 不适用于部分应用场景:Boyer-Moore 算法在某些特定情况下可能不如其他算法,例如当模式串中包含大量重复的字符时,算法的效率可能不如 Rabin-Karp 算法。

  3. 需要额外的预处理时间:Boyer-Moore 算法在匹配之前需要进行预处理,构建坏字符规则表和好后缀规则表,这可能会增加算法的启动时间。

综上所述,Boyer-Moore 算法在大多数情况下具有较高的匹配效率和适用性广泛的优点,但在某些特定情况下可能存在一些缺点。在实际应用中,需要根据具体的场景和需求选择合适的字符串匹配算法。

3、Boyer-Moore 的应用场景

Boyer-Moore 算法在字符串匹配领域有广泛的应用场景,特别适用于以下情况:

  1. 长模式串匹配:当模式串较长时,Boyer-Moore 算法的效率比其他字符串匹配算法更高。它通过坏字符规则和好后缀规则的匹配跳过尽可能多的比较操作,从而实现快速的匹配。

  2. 大型文本串匹配:对于大型文本串,Boyer-Moore 算法能够利用坏字符规则和好后缀规则快速定位模式串的移动距离,从而提高匹配效率。

  3. 包含重复字符的模式串匹配:Boyer-Moore 算法对于包含重复字符的模式串的匹配效果较好。它通过坏字符规则和好后缀规则的匹配,能够跳过重复字符的比较操作,从而提高匹配速度。

  4. 文本搜索引擎:Boyer-Moore 算法被广泛应用于文本搜索引擎中,用于实现关键字的快速匹配和搜索。它能够高效地处理大量的文本数据,并返回匹配结果。

总的来说,Boyer-Moore 算法适用于长模式串匹配、大型文本串匹配、包含重复字符的模式串匹配以及文本搜索引擎等应用场景。它通过利用坏字符规则和好后缀规则,能够快速定位模式串的移动距离,从而提高匹配效率。

4、Boyer-Moore 的原理

Boyer-Moore 算法是一种高效的字符串匹配算法,它利用了两个规则来快速定位模式串在文本串中的位置,从而提高匹配效率。这两个规则分别是坏字符规则(Bad Character Rule)和好后缀规则(Good Suffix Rule)。

  1. 坏字符规则:

    • 当发现模式串中的某个字符与文本串中的字符不匹配时,可以将模式串向右移动,使得该不匹配字符对齐文本串中的下一个字符。
    • 如果文本串中的字符在模式串中不存在,那么可以将模式串整体向右移动,直接跳过该字符。
  2. 好后缀规则:

    • 当模式串中的某个后缀与文本串中的子串匹配时,可以将模式串向右移动,使得该后缀对齐文本串中的子串。
    • 如果文本串中的子串在模式串中找不到匹配的后缀,那么可以将模式串整体向右移动,直接跳过该子串。

Boyer-Moore 算法利用这两个规则来选择移动的距离,以尽量减少比较操作的次数。具体实现时,可以预先计算出每个字符在模式串中最右出现的位置,以及每个后缀在模式串中的最右出现位置。然后根据坏字符规则和好后缀规则,选择移动的距离。

通过利用坏字符规则和好后缀规则,Boyer-Moore 算法能够快速定位模式串在文本串中的位置,从而提高字符串匹配的效率。它在实际应用中被广泛使用,特别适用于长模式串匹配和大型文本串匹配的场景。

5、Boyer-Moore 的使用案例

Boyer-Moore算法在字符串匹配领域有着广泛的应用,以下是一些使用Boyer-Moore算法的案例:

  1. 文本编辑器中的查找功能:许多文本编辑器使用Boyer-Moore算法来实现快速查找功能。当用户在文本中输入关键字进行查找时,编辑器可以利用Boyer-Moore算法快速定位匹配的位置,提高查找效率。

  2. 字符串搜索引擎:搜索引擎需要对大量的文本进行索引和搜索。Boyer-Moore算法可以用于字符串搜索引擎中的关键字匹配,帮助搜索引擎快速定位匹配的文档。

  3. 文件压缩和解压缩:Boyer-Moore算法可以应用于文件压缩和解压缩算法中的字符串匹配部分。通过使用Boyer-Moore算法,可以快速定位重复的字符串,从而实现高效的压缩和解压缩。

  4. 数据库系统中的模式匹配:在数据库系统中,模式匹配是一个重要的操作。Boyer-Moore算法可以用于模式匹配中的字符串匹配部分,帮助数据库系统快速定位匹配的数据。

总之,Boyer-Moore算法在字符串匹配领域有着广泛的应用,能够提高字符串匹配的效率。无论是在文本编辑器、搜索引擎、文件压缩和解压缩,还是数据库系统中,Boyer-Moore算法都可以发挥重要作用。

6、使用 Java 实现 Boyer-Moore

package com.pany.camp.algorithm;

/**
 *
 * @description: Boyer-Moore 字符串匹配算法
 * @copyright: @Copyright (c) 2022
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0
 * @createTime: 2023-06-28 21:17
 */
public class BoyerMoore {
   
   

    private int[] right;
    private String pattern;

    public BoyerMoore(String pattern) {
   
   
        this.pattern = pattern;
        int patternLength = pattern.length();
        int alphabetSize = 256; // ASCII字符集大小
        right = new int[alphabetSize];
        for (int i = 0; i < alphabetSize; i++) {
   
   
            right[i] = -1; // 初始化为-1,表示字符不在模式中
        }
        for (int i = 0; i < patternLength; i++) {
   
   
            right[pattern.charAt(i)] = i; // 记录每个字符在模式中最右出现的位置
        }
    }

    public int search(String text) {
   
   
        int textLength = text.length();
        int patternLength = pattern.length();
        int skip;
        for (int i = 0; i <= textLength - patternLength; i += skip) {
   
   
            skip = 0;
            for (int j = patternLength - 1; j >= 0; j--) {
   
   
                if (pattern.charAt(j) != text.charAt(i + j)) {
   
   
                    skip = Math.max(1, j - right[text.charAt(i + j)]);
                    break;
                }
            }
            if (skip == 0) {
   
   
                return i; // 找到匹配的位置
            }
        }
        return -1; // 未找到匹配的位置
    }

    public static void main(String[] args) {
   
   
        String text = "ABABABABCDABABCABAB";
        String pattern = "ABABCABAB";
        BoyerMoore bm = new BoyerMoore(pattern);
        int index = bm.search(text);
        if (index != -1) {
   
   
            System.out.println("Pattern found at index " + index);
        } else {
   
   
            System.out.println("Pattern not found");
        }
    }
}

输出如下:

Pattern found at index 10

Process finished with exit code 0

1686494501743.jpg

💕💕 本文由激流原创,首发于CSDN博客,博客主页 https://blog.csdn.net/qq_37967783?spm=1010.2135.3001.5421
💕💕喜欢的话记得点赞收藏啊
1687869804912.jpg

目录
相关文章
|
3天前
|
自然语言处理 算法 搜索推荐
字符串相似度算法完全指南:编辑、令牌与序列三类算法的全面解析与深入分析
在自然语言处理领域,人们经常需要比较字符串,这些字符串可能是单词、句子、段落甚至是整个文档。如何快速判断两个单词或句子是否相似,或者相似度是好还是差。这类似于我们使用手机打错一个词,但手机会建议正确的词来修正它,那么这种如何判断字符串相似度呢?本文将详细介绍这个问题。
172 1
|
5天前
|
数据采集 算法 JavaScript
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法
JavaScript字符串搜索涵盖`indexOf`、`includes`及KMP算法。`indexOf`返回子字符串位置,`includes`检查是否包含子字符串。KMP是高效的搜索算法,尤其适合长模式匹配。示例展示了如何在数据采集(如网页爬虫)中使用这些方法,结合代理IP进行安全搜索。代码示例中,搜索百度新闻结果并检测是否含有特定字符串。学习这些技术能提升编程效率和性能。
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法
|
4天前
|
算法 Java
KMP算法详解及其在字符串匹配中的应用
KMP算法详解及其在字符串匹配中的应用
|
4天前
|
算法 Java
KMP算法详解及其在字符串匹配中的应用
KMP算法详解及其在字符串匹配中的应用
|
11天前
|
存储 算法 Java
Java数据结构与算法:用于高效地存储和检索字符串数据集
Java数据结构与算法:用于高效地存储和检索字符串数据集
|
13天前
|
算法 Java
Java数据结构与算法:字符串匹配算法之暴力匹配
Java数据结构与算法:字符串匹配算法之暴力匹配
|
13天前
|
算法 Java
Java数据结构与算法:字符串匹配算法之KMP算法
Java数据结构与算法:字符串匹配算法之KMP算法
|
2天前
|
机器学习/深度学习 算法 调度
Matlab|基于改进鲸鱼优化算法的微网系统能量优化管理matlab-源码
基于改进鲸鱼优化算法的微网系统能量管理源码实现,结合LSTM预测可再生能源和负荷,优化微网运行成本与固定成本。方法应用于冷热电联供微网,结果显示经济成本平均降低4.03%,提高经济效益。代码包括数据分段、LSTM网络定义及训练,最终展示了一系列运行结果图表。
|
7天前
|
算法 安全 数据库
基于结点电压法的配电网状态估计算法matlab仿真
**摘要** 该程序实现了基于结点电压法的配电网状态估计算法,旨在提升数据的准确性和可靠性。在MATLAB2022a中运行,显示了状态估计过程中的电压和相位估计值,以及误差随迭代变化的图表。算法通过迭代计算雅可比矩阵,结合基尔霍夫定律解决线性方程组,估算网络节点电压。状态估计过程中应用了高斯-牛顿或莱文贝格-马夸尔特法,处理量测数据并考虑约束条件,以提高估计精度。程序结果以图形形式展示电压幅值和角度估计的比较,以及估计误差的演变,体现了算法在处理配电网状态估计问题的有效性。
|
4天前
|
数据采集 存储 算法
基于BP算法的SAR成像matlab仿真
**摘要:** 基于BP算法的SAR成像研究,利用MATLAB2022a进行仿真。SAR系统借助相对运动合成大孔径,提供高分辨率图像。BP算法执行回波数据预处理、像素投影及图像重建,实现精确成像。优点是高精度和强适应性,缺点是计算量大、内存需求高。代码示例展示了回波生成、数据处理到插值显示的全过程。