算法——字符串匹配算法——BM(Boyer-Moore) 算法

news2024/11/23 19:04:52

字符串匹配算法——BM (Boyer-Moore) 算法

  • 概述
  • 场景一 坏字符场景且模式串中没有匹配字符
  • 场景二 坏字符场景且模式串中有匹配字符
  • 场景三 好后缀场景且模式串中没有匹配字符
  • 场景四 好后缀场景且模式串中有匹配字符
  • 场景五 好后缀场景且模式串中有匹配子串后缀字符
  • 总结

概述

         字符串匹配算法:在一个大的字符串T中搜索某个字符串P的所有出现位置,例如字符串T为abcdef,模式串(搜索词)P为bc。通过字符串匹配算法返回的位置为1。
         常见的算法包含:BF算法(Brute Force 暴力算法)、RK算法(Rabin-Karp 哈希匹配算法)、BM算法(Boyer-Moore 坏字符和好后缀算法)、KMP算法(最长可匹配前后缀子串算法),本文主要介绍Bm算法。

         Bm算法整体流程大致分为3步。
         1. 从后向前匹配逐个字符:首先,从后向前逐个匹配字符,如果字符不相同则称为坏字符,如果字符相同则为好后缀。然后再根据好后缀和坏字符计算模式串(搜索词)的移动位置。
         2. 如果模式串(搜索词)P没有完全匹配字符串T。根据好后缀和坏字符的位置计算模式串(搜索词)向后移动的位置。
                  2.1 坏字符计算方式:移动位数=坏字符在模式串的位置 - 模式串上一次的位置
                  2.2 好后缀计算方式:移动位数=好后缀在模式串的位置 - 模式串上一次的位置

         3. 重复上述步骤,如果模式串匹配到字符串则返回对应的位置,如果没有能匹配的字符则返回 -1。

         本文通过5个场景说明BM(Boyer-Moore) 算法的执行步骤。

动画算法总体概览图: 动画算法总体概览图

文章中使用的动画网站地址,限 pc:
场景一:坏字符场景且模式串中没有匹配字符 算法动画
http://www.donghuasuanfa.com/platform/portal?pc=boyer-moore
场景二:坏字符场景且模式串中有匹配字符 算法动画
http://www.donghuasuanfa.com/platform/portal?pc=boyer-moore-case2
场景三:好后缀场景且模式串中没有匹配字符
http://www.donghuasuanfa.com/platform/portal?pc=boyer-moore-case3
场景四:好后缀场景且模式串中有匹配字符
http://www.donghuasuanfa.com/platform/portal?pc=boyer-moore-case4
场景五:好后缀场景且模式串中有匹配子串后缀字符
http://www.donghuasuanfa.com/platform/portal?pc=boyer-moore-case5

场景一 坏字符场景且模式串中没有匹配字符

        首先从后往前逐个匹配字符,因为字符串的k和模式串(搜索词)的d不相符,所以认为k是坏字符,因此无需再比较剩余字符。
        然后计算模式串(搜索词)向后移动多少位置,位置计算公式为:移动位数=坏字符在模式串的位置 - 模式串上一次的位置
        坏字符在模式串的位置:示例中k为坏字符,所以对应的模式串的位置为3。
        模式串上一次的位置:坏字符k寻找位置的过程为逐个比较模式串之前的字符,如果匹配则返回对应的位置,如果不匹配则返回-1。当前场景为没有能匹配坏字符的场景,所以上一个位置为-1。
        因此移动位置的计算结果为 3-(-1)=4。整体过程如下图1-1所示。
请添加图片描述

图1-1

        接下来移动模式串,移动的位置为4,过程入如下图1-2所示。
请添加图片描述

图1-2

场景二 坏字符场景且模式串中有匹配字符

        场景二也是坏字符场景。首先从后往前逐个匹配字符,因为字符串的k和模式串(搜索词)的d不相符,所以认为k是坏字符,因此无需再比较剩余字符。
        然后计算模式串(搜索词)向后移动多少位置,位置计算公式为:移动位数=坏字符在模式串的位置 - 模式串上一次的位置
        坏字符在模式串的位置:示例中k为坏字符,所以对应的模式串的位置为3。
        模式串上一次的位置:坏字符k寻找位置的过程为逐个比较模式串之前的字符,如果匹配则返回对应的位置,如果不匹配则返回-1。当前场景为有能匹配坏字符的场景,除了坏字符外,模式串上一个坏字符的位置为1,所以上一个位置为1。
        因此移动位置的计算结果为 3-1 =2。整体过程如下图2-1所示。
请添加图片描述

        接下来移动模式串,移动的位置为2,过程入如下图2-2所示。
请添加图片描述

图2-2

场景三 好后缀场景且模式串中没有匹配字符

        场景三为好后缀场景。首先从后往前逐个匹配字符,因为字符串的kd和模式串(搜索词)的kd相符,所以认为kd是好后缀。同时因为字符串的c和模式串(搜索词)的t不相符,所以认为c是坏字符。因此无需再比较剩余字符。
        寻找好后缀和坏字符如下图3-1所示。
请添加图片描述

图3-1

        然后计算模式串(搜索词)向后移动多少位置,如果字符串同时包含好后缀和坏字符则需要分别计算需要移动的位置。计算后选择移动位置多的进行移动。
        坏字符位置计算公式为:移动位数=坏字符在模式串的位置 - 模式串上一次的位置
        好后缀位置计算公式为:移动位数=好后缀在模式串的位置 - 模式串上一次的位置

        根据好后缀计算移动的位置。好后缀kd对应的模式串的位置为最右侧字符的位置,最右侧字符为d,所以位置为4。然后再寻找kd在模式串上一次的位置,由于模式串前三个字符nut都不包含kd,所以好后缀在模式串上一次的位置为-1,因此计算出移动位置为5。整体过程如下图3-2所示。

请添加图片描述

图3-2

        好后缀计算移动的位置除了计算好后缀字符串还需要计算好后缀的子串,子串即逐个去掉好后缀的左侧字符。示例中kd去掉左侧的字符k后保留的子串只有一个d,并且d所对应的模式串的位置依然为4。子串比较规则为只需要比较模式串的头部即可,无需逐个比较模式串的字符。因为子串d与模式串首个字符n不相等,所以好后缀在模式串上一次的位置为-1,因此计算出移动位置为5。整体过程如下图3-3所示。

请添加图片描述

图3-3

        继续计算坏字符场景,坏字符场景计算过程和场景1、2一致,此处不再赘述,经计算后坏字符的移动位置为3。整体过程如下图3-4所示。

请添加图片描述

图3-4

        当同时包含好后缀和坏字符时,则选择移动位置最大的进行移动,因为好后缀移动位置为5,坏字符移动位置为3.所以模式串整体移动5的位置。整体过程如下图3-5 所示。

请添加图片描述

图3-5

场景四 好后缀场景且模式串中有匹配字符

        场景四也为好后缀场景。首先从后往前逐个匹配字符,因为字符串的ct和模式串(搜索词)的ct相符,所以认为ct是好后缀。同时因为字符串的m和模式串(搜索词)的k不相符,所以认为m是坏字符。因此无需再比较剩余字符。整体过程如下图4-1所示。
请添加图片描述

图4-1

        然后计算模式串(搜索词)向后移动多少位置,如果字符串同时包含好后缀和坏字符则需要分别计算需要移动的位置。计算后选择移动位置多的进行移动。
        坏字符位置计算公式为:移动位数=坏字符在模式串的位置 - 模式串上一次的位置
        好后缀位置计算公式为:移动位数=好后缀在模式串的位置 - 模式串上一次的位置

        当前场景为好后缀在模式串前有匹配字符,
        好后缀ct对应的模式串的位置通常为最右侧字符的位置,最右侧字符为t,所以位置为8。然后再寻找ct在模式串上一次的位置,由于模式串第4、5个字符为ct,所以好后缀在模式串上一次的位置为5,因此计算出移动位置为3。

        好后缀在模式串能够匹配成功后如果再按照子串移动会发生过度移动,所以无需再比较计算好后缀的t子串的移动位置

        整体计算过程如下图4-2 所示。

请添加图片描述

图4-2

        继续计算坏字符场景,坏字符场景计算过程和场景1、2一致,此处不再赘述,经计算后坏字符的移动位置为3。整体过程如下图4-3所示。

请添加图片描述

图4-3

        当同时包含好后缀和坏字符时,则选择移动位置最大的进行移动,示例中好后缀和坏字符计算结果都为3,所以移动的位置为3。整体过程如下图4-4 所示。

请添加图片描述

图4-4

        因为好后缀在模式串匹配成功的移动位置为最优的移动位置。所以无需再计算好后缀的子串和坏字符的移动位置,读者如果有疑议可自行找例子计算。

场景五 好后缀场景且模式串中有匹配子串后缀字符

        场景五也为好后缀场景。首先从后往前逐个匹配字符,因为字符串的kct和模式串(搜索词)的kct相符,所以认为kct是好后缀。同时因为字符串的m和模式串(搜索词)的s不相符,所以认为m是坏字符。因此无需再比较剩余字符。整体过程如下图5-1所示。

请添加图片描述

图5-1

        根据好后缀计算移动的位置。好后缀kct对应的模式串的位置为最右侧字符的位置,最右侧字符为t,所以位置为5。然后再寻找kct在模式串上一次的位置,由于模式串前三个字符tms都不包含kd,所以好后缀kct在模式串上一次的位置为-1,因此计算出移动位置为6。整体过程如下图5-2所示。

请添加图片描述

图5-2

        好后缀计算移动的位置除了计算好后缀字符串还需要计算好后缀的子串,子串即逐个去掉好后缀的左侧字符。示例中kct依次去掉左侧的字符后保留的子串为ct、t。ct、t这俩个子串在模式串的位置以最右侧字符为准,所以位置为5。
        ct子串与模式串前俩个字母tm比较,因为不相符,所以子串ct的上一个位置为-1,因此ct子串计算移动位置为6。
        ct子串计算过程如下图5-3所示。
请添加图片描述

图5-3

        t子串与模式串首个字母t比较,因为相符,所以子串t的上一个位置为0,因此t子串计算移动位置为5。因为好后缀有多个计算结果,所以多个好后缀之间的移动位置取最短的长度,以防止过度移动。所以当前示例好后缀的移动距离为5。
        t子串计算过程如下图5-4所示。

请添加图片描述

图5-4

        继续计算坏字符场景,坏字符场景计算过程和场景1、2一致,此处不再赘述,经计算后坏字符的移动位置为3。整体过程如下图5-5所示。

请添加图片描述

图5-5

        当同时包含好后缀和坏字符时,则选择移动位置最大的进行移动,示例中好后缀的计算结果为5,坏字符计算结果为1,所以移动的位置为5。整体过程如下图5-6 所示。

请添加图片描述

图5-6

        所有示例结束。

总结

         Bm算法整体流程大致分为3步。
         1. 从后向前匹配逐个字符:首先,从后向前逐个匹配字符,如果字符不相同则称为坏字符,如果字符相同则为好后缀。然后再根据好后缀和坏字符计算模式串(搜索词)的移动位置。
         2. 如果模式串(搜索词)P没有完全匹配字符串T。根据好后缀和坏字符的位置计算模式串(搜索词)向后移动的位置。
                  2.1 坏字符计算方式:移动位数=坏字符在模式串的位置 - 模式串上一次的位置
                  2.2 好后缀计算方式:移动位数=好后缀在模式串的位置 - 模式串上一次的位置

         3. 重复上述步骤,如果模式串匹配到字符串则返回对应的位置,如果没有能匹配的字符则返回 -1。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/668808.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

EfficientDet-pytorch目标检测训练

目录 1. EfficientDet-pytorch版本代码下载 2.数据集准备 2.1数据集格式 2.2 定义自己数据集的yml文件 3. 训练配置 4.模型评估 5.测试模型性能 1. EfficientDet-pytorch版本代码下载 GitHub - zylo117/Yet-Another-EfficientDet-Pytorch: The pytorch re-implement…

chatgpt赋能python:Python提取指定数据的方法与技巧

Python提取指定数据的方法与技巧 在SEO优化中,数据的提取和分析是非常重要的环节之一。而Python具有方便易用的数据处理能力,成为了SEO优化工程师们的重要工具之一。本文将介绍Python中提取指定数据的方法与技巧,以及实现的具体案例。 数据…

python:使用Scikit-image库进行单波段遥感图像颜色直方图特征提取(histogram)

作者:CSDN @ _养乐多_ 本文记录了使用Scikit-image库对单波段遥感图像做颜色直方图特征提取的代码。 文章目录 一、颜色直方图特征详解二、代码一、颜色直方图特征详解 颜色直方图是一种用于描述图像中颜色分布的特征表示方法。它将图像中每个像素的颜色值作为输入,统计并显…

Java 基础进阶篇(十七):反射概述及获取对象的方式

文章目录 一、反射概述二、反射获取类对象三、反射获取构造器对象四、反射获取成员变量对象五、反射获取方法对象六、 反射的作用6.1 绕过编译阶段为集合添加数据6.2 通用框架的底层原理 一、反射概述 反射是指对于任何一个Class类,在 “运行的时候”,不…

PHP实战开发23-PHP结合Nginx获取用户真实IP地址

文章目录 一、前言二、关于用户IP的背景知识2.1 HTTP请求2.2 HTTP代理服务器2.3 X-Forwarded-For头部 三、代码实现3.1 Nginx配置3.2 PHP代码处理 总结 一、前言 本文已收录于PHP全栈系列专栏:PHP快速入门与实战 在Web应用程序中,IP地址是常见的数据项…

Flink 学习四 Flink 基础架构

Flink 学习四 Flink 基础架构&算子链&槽位 文章大部分数据来源 : https://nightlies.apache.org/flink/flink-docs-release-1.14/docs/concepts/flink-architecture/ Flink 是一个分布式系统,需要有效的分配和管理计算资源才可以执行流式程序; 集成了常见的资源管理…

chatgpt赋能python:Python简介

Python简介 Python是一种高级编程语言,具有易读性和简洁性的特点。它被广泛使用于Web开发、数据科学、人工智能、机器学习和自动化测试等领域。Python也是一种非常适合新手学习编程的语言。 在本篇文章中,我们将讨论如何使用Python提取指定内容以进行S…

【BMS】电池包硬件方案选型指南

🔋电池包硬件方案选型指南🔋 BMS硬件系统需求主要包括:测温模块、测流模块、测压模块、系统电源、保护电路、故障检测电路,本文阐述各个功能模块在不同场景下的电池包硬件系统方案选择。 一、测温 NTC(热敏电阻) 电池包测温一般包括表皮温度、内部温度、PCB温度(极片布…

[自定义组件]微信小程序自定义组件实现缩略图和原图分离及可缩放效果

目录 目标及基础环境背景 实现原理左右滑动缩放图片菜单 开发实现自定义组件wxml组件结构wxss 样式控制js定义属性及回调json声明为组件 使用添加组件声明及地址声明为全局组件(也可声明为局部)声明为全局组件(也可以声明为全局组件)使用组件 效果展示 附…

pycharm安装, 汉化 , 使用教程

目录 1.下载安装包 2.汉化 3.使用 1.下载安装包 访问Pycharm官网 根据自己的操作系统下载对应版本的Pycharm Community或Professional Edition。 2.汉化 点击“file”选项,然后点击“setting”,再点击“plugins”选项; 输入“Chinese”找…

使用Frp进行反向代理实现远程桌面控制[teamviewer/nomachine]

.使用Frp进行反向代理实现远程桌面控制 V1.0.0 – by Holden Date : 2023-06-20 文章目录 .使用Frp进行反向代理实现远程桌面控制1. 简介2. 工具准备3. 服务器端搭建4. 受控端配置&&运行teamviewer5. 控制机端运行teamviewer6. 切换成nomachine 1. 简介 ​ frp 是一…

winform多语言资源管理

SailingEase WinForm Framework WinForm开发框架开发手册:http://docs.shengxunwei.com/Home/Browser/sewinformfw/ 这是我2010年左右,写 Winform IDE (使用 .NET WinForm 开发所见即所得的 IDE 开发环境,实现不写代码直接生成应用…

什么是算法

有人说程序算法数据结构,虽说这样的认为有失偏颇,一个程序决定的东西实在太多,但某些方面也说明了算法是很重要的(数据结构承上启下,最终也是要为算法服务)。 算法是用来解决问题的,要理解什么是…

AI Image Codec技术落地实践

AI Codec自2016年首次提出以来,众多海内外高校、企业研究院等机构对此展开了广泛研究。6年时间里,AI Codec 的SOTA方案的压缩性能已经超越了H.266(最新的传统Codec标准),展现了强大的技术潜力。但受限于计算复杂度、非标等原因,AI…

Vue中的JSX的特性

JSX简介 JSX是一种Javascript的语法扩展&#xff0c;即具备了Javascript的全部功能&#xff0c;同时又兼具html的语义化和直观性。它可以让我们在JS中写模板语法&#xff1a; const el <div>Vue 2</div>; 复制代码上面这段代码既不是 HTML 也不是字符串&#xf…

java阿里云sls基于LoghubAppender自定义日志上传

1、背景&#xff1a;阿里sls日志提供快捷日志平台&#xff0c;平替elk公司使用这个日志服务&#xff0c;需要对接写入日志 目前日志集成有3种 1&#xff09;基于封装manager手动写日志手动send 弊端&#xff1a;本地日志和阿里云日志共用日志代码很臃肿 2&#xff09;基于云服…

开启数字时代,分享电脑监控和录制工具

近年来&#xff0c;随着网络技术的快速发展和普及&#xff0c;电脑屏幕录制和监控越来越成为企业、学校、家庭等不可或缺的工具。无论是在线教学、远程工作&#xff0c;还是家长对孩子上网行为的关注&#xff0c;电脑屏幕录制和监控都具有极大的帮助和重要性。今天就给大家推荐…

【Visual Studio】使用 C++ 语言,配合 Qt,开发了一个串口通信界面

知识不是单独的&#xff0c;一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏&#xff1a;Visual Studio。 文章目录 1. 获取串口名字1.1 文件 GUI.ui1.2 文件 GUI.h1.3 文件 GUI.cpp 2. 配置串口连接2.1 文件 GUI.ui2.2 文件 GUI.h2.3 文件 GUI.cpp 3. 配置串口连接…

chatgpt赋能python:Python排错大全:10年经验总结,快速定位并解决问题!

Python排错大全&#xff1a;10年经验总结&#xff0c;快速定位并解决问题&#xff01; 作为一名有着10年Python编程经验的工程师&#xff0c;在这篇文章中&#xff0c;我将详细介绍常见的Python排错技巧&#xff0c;以及我在实际工作中使用的一些技巧和最佳实践。我们将学习如…

《网络安全0-100》安全策略制定

安全策略制定 安全策略制定是指制定一系列的规范、标准和 流程&#xff0c;以保护企业或组织的信息资源和业务活 动&#xff0c;确保其安全性和可靠性。安全策略制定通 常包括以下几个步骤&#xff1a; 风险评估&#xff1a;对企业或组织的信息系统进行全面 评估&#xff…