Java中BM(Boyer-Moore)算法的图解与实现

yizhihongxing

Java中BM(Boyer-Moore)算法的图解与实现

前言

本文主要介绍在Java中实现BM算法。BM算法是一种高效的模式匹配算法,其核心思想是,对于模式串的每个字符,在匹配串中寻找该字符时,优先从模式串的尾部开始匹配,以减少匹配步骤。本文将详细介绍BM算法的流程,并提供两个示例以帮助读者更好地理解该算法。

算法流程

  1. 计算字符偏移量表
  2. 字符集假设有m个字符
  3. 索引表(下表从0开始)b数组,b[i]表示模式串中,左侧第i个字符(即从左往右第i+1个)在模式串中最后一次出现的位置,如果不存在则为-1
  4. sbc数组,sbc[i]表示在模式串中字符i的偏移量,即可以向右移动sbc[i]使得模式串中字符i与匹配串的当前匹配位置对齐
  5. 匹配模式串
  6. 从匹配串的开头开始,以步长i+j为递增的方式扫描匹配串,i表示匹配串的第一位,j表示模式串的第一位
  7. 对于每一次的匹配,从模式串的尾部开始逐个检测字符,如果遇到不匹配的字符跳过,直到找到相同的字符为止
  8. 如果匹配完整个模式串,则返回当前匹配的起始位置;否则,根据偏移量表移动模式串,进行下一次匹配

代码实现

public class BoyerMoore {
    private static int[] buildBC(char[] pattern) {
        int[] bc = new int[256];
        for (int i = 0; i < bc.length; i++) {
            bc[i] = -1;
        }
        for (int i = 0; i < pattern.length; i++) {
            bc[pattern[i]] = i;
        }
        return bc;
    }

    private static int[] buildSBC(char[] pattern) {
        int[] sbc = new int[256];
        for (int i = 0; i < sbc.length; i++) {
            sbc[i] = pattern.length;
        }
        for (int i = 0; i < pattern.length - 1; i++) {
            sbc[pattern[i]] = pattern.length - i - 1;
        }
        return sbc;
    }

    public static int bm(char[] text, char[] pattern) {
        int[] bc = buildBC(pattern);
        int[] sbc = buildSBC(pattern);
        int i = 0;
        while (i <= text.length - pattern.length) {
            int j = pattern.length - 1;
            while (j >= 0 && pattern[j] == text[i + j]) {
                j--;
            }
            if (j < 0) {
                return i;
            } else {
                i += Math.max(sbc[text[i + j]] - pattern.length + j + 1, bc[text[i + j]]);
            }
        }
        return -1;
    }
}

示例说明

示例一

文本串:ABCBABACABCBACABCBAC
模式串:CBAC

char[] text = "ABCBABACABCBACABCBAC".toCharArray();
char[] pattern = "CBAC".toCharArray();
int index = BoyerMoore.bm(text, pattern);
System.out.println(index); // 输出 11

运行结果:该示例中匹配到了第一个模式串CBAC,其起始位置为11,可以发现BM算法对于长文本和短模式具有很高的匹配效率。

示例二

文本串:ADFHdjkakoksjdfaDHDSD
模式串:ab

char[] text = "ADFHdjkakoksjdfaDHDSD".toCharArray();
char[] pattern = "ab".toCharArray();
int index = BoyerMoore.bm(text, pattern);
System.out.println(index); // 输出 -1

运行结果:该示例中匹配模式串失败,返回-1。需要注意的是,模式串不区分大小写,所以示例中的"AB"和"ab"实际上是等效的,匹配结果将一致。

结论

通过以上的流程介绍和实例说明,我们可以看到BM算法的匹配效率很高,特别适合处理长文本和短模式的匹配问题。此外,通过实现该算法,也可以加深理解算法的核心思想,对于日后的算法学习和应用都会有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java中BM(Boyer-Moore)算法的图解与实现 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • Java经典排序算法之插入排序

    Java经典排序算法之插入排序 插入排序算法简介 插入排序是一种简单直观的排序算法,它的基本思想是将待排序序列分为已排序和未排序两部分,初始时将第一个元素视为已排序序列,将其他元素视为未排序序列。然后依次将未排序序列中的元素插入到已排序序列中的正确位置。在插入元素时,需要从右到左比较已排序序列中的元素,找到插入元素的正确位置。 插入排序算法示例 假设我们要对…

    Java 2023年5月19日
    00
  • 栈区的作用是什么?

    栈区(Stack)是一种用于存储方法调用和局部变量的内存区域。栈区线程私有的,大小可以通过 -Xss 参数进行设置。 使用栈区,需要注意以下几点: 在程序开发中需要合理使用存,免出现栈溢出等问题。 在方法调用过程中,需要注意方法的嵌套深度,避免出现栈溢出等问题。 在方法中定义局部变量时,需要注意变量的作用域和生命周期,避免出现变量被错误地使用等问题。 以下是…

    Java 2023年5月12日
    00
  • MyBatis-Plus工具使用之EntityWrapper解析

    如何使用 MyBatis-Plus 的 EntityWrapper 来查询数据,以下是详细的攻略: 前置条件 要使用 EntityWrapper,需要先添加 MyBatis-Plus 的依赖,如下: <dependency> <groupId>com.baomidou</groupId> <artifactId&gt…

    Java 2023年5月20日
    00
  • java性能优化四种常见垃圾收集器汇总

    Java性能优化四种常见垃圾收集器汇总 概述 垃圾收集是Java语言中非常重要的一部分,垃圾收集器的选择直接影响到JVM的性能和GC的效率。本文将介绍Java中常见的四种垃圾收集器,包括串行收集器、并行收集器、CMS收集器和G1收集器。同时,将详细介绍不同垃圾收集器之间的区别及他们的使用场景。 串行收集器 串行收集器是最简单的收集器,是JVM默认的垃圾收集器…

    Java 2023年5月19日
    00
  • 10k+点赞的 SpringBoot 后台管理系统教程详解

    首先我们需要明确一下什么是SpringBoot后台管理系统。SpringBoot是一个Java开发框架,它能够帮助开发者快速搭建一个Java Web应用程序,尤其适用于后台管理系统的开发。而SpringBoot后台管理系统,就是指采用SpringBoot框架开发的一个管理后台,用于管理数据和业务逻辑。 接下来,我将详细讲解如何制作一个10k+点赞的Sprin…

    Java 2023年5月15日
    00
  • 教你怎么用JSP统计网站访问人数

    下面我将详细讲解如何使用 JSP 统计网站访问人数的完整攻略。 1. 确定需求和实现方式 首先,我们需要确定我们统计访问人数的具体需求。一般来说,统计网站访问人数可以通过记录网站访问量或者记录独立访客数量来实现。 对于记录网站访问量,一般常用的方式是在网站的每个页面中嵌入一个计数器。当用户访问网站的时候,计数器会自动加一。而对于独立访客数量的记录,则需要在用…

    Java 2023年6月15日
    00
  • Java的Struts框架报错“NullActionMappingException”的原因与解决办法

    当使用Java的Struts框架时,可能会遇到“NullActionMappingException”错误。这个错误通常由以下原因之一起: 配置错误:如果配置文件中没有正确配置,则可能会出现此错误。在这种情况下,需要检查文件以解决此问题。 ActionMapping对象为空:如果ActionMapping对象为空,则可能会出现此错误。在这种情况下,需要检查A…

    Java 2023年5月5日
    00
  • 小程序实现带年月选取效果的日历

    下面是关于小程序实现带年月选取效果的日历的完整攻略: 一、实现思路 获取当前日期的年和月以及当月的天数; 使用数据渲染模板,并在相应的日期上添加样式; 实现滑动切换月份功能; 添加点击事件,实现从日历中选择日期并将该日期传递给父组件。 二、具体实现 下面我们将通过两个示例来说明具体实现步骤。 示例一 首先,我们需要在 wxml 文件中编写日历的结构,并通过 …

    Java 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部