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

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日

相关文章

  • 手写简版kedis分布式key及value服务的实现及配置

    下面是实现“手写简版kedis分布式key及value服务的实现及配置”的完整攻略: 1. 简介 kedis是一个分布式缓存系统,类似于redis和memcached,但使用协议更为简单和高效。本攻略将介绍如何手写一个简版的kedis,实现分布式key及value服务的配置。 2. 实现 2.1. 算法选择 kedis的实现依赖于哈希算法,用于计算key的h…

    Java 2023年5月20日
    00
  • Spring MVC 拦截器实现登录

    针对Spring MVC的拦截器实现登录,我可以提供以下完整攻略: 一、拦截器的介绍 在Spring MVC中,拦截器(Interceptor)是一种拦截请求的机制,类似于Servlet中的过滤器(Filter),可以在请求到达Controller之前或者之后对请求进行拦截和处理。借助拦截器,可以实现常见的业务需求,如日志记录、权限校验、登录校验等等。 二、…

    Java 2023年6月15日
    00
  • SpringBoot整合MybatisPlus的教程详解

    SpringBoot整合MybatisPlus的教程详解 本篇文章将介绍SpringBoot如何整合MybatisPlus,并给出两个示例供参考。 简介 SpringBoot是一个快速构建Spring应用程序的框架,整合了大量常用的第三方库。MybatisPlus是基于Mybatis的增强工具,简化了在Mybatis中的开发流程。 准备工作 在开始前,请确保…

    Java 2023年5月19日
    00
  • JSP登录中Session的用法实例详解

    JSP登录中Session的用法实例详解 什么是Session Session 是在服务器端存储用户信息的最常用的方式之一。它能够跨越不同的请求并在整个会话期间保持这些信息。Session 变量存储在服务器上,当用户浏览网站时,它们的信息会被传输到服务器进行处理并返回响应页面。在 Java 中可以使用 HttpSession 对象来操作 Session。 S…

    Java 2023年6月15日
    00
  • Java Servlet和JSP教程

    下面就来详细讲解一下“Java Servlet和JSP教程”的完整攻略。 一、背景介绍 Java Servlet和JSP是Web应用程序开发中非常重要的两个技术,Servlet可以处理HTTP请求并返回HTTP响应,而JSP则可以将Java代码嵌入到HTML中,方便动态生成Web页面。本教程主要介绍Servlet和JSP的基本知识,包括Servlet API…

    Java 2023年5月23日
    00
  • Java之一文详解String字符串的用法

    Java之一文详解String字符串的用法 1. 什么是字符串(String)? 在 Java 语言中,字符串是一组用双引号括起来的字符序列,例如:”Hello World”。字符串是Java中的常见数据类型之一,类型名为String。 2. 如何声明字符串类型变量? 在 Java 中声明字符串类型变量,必须使用关键字String,例如: String st…

    Java 2023年5月26日
    00
  • jdbc实现图书馆借阅系统

    JDBC实现图书馆借阅系统 简介 JDBC是Java Database Connectivity的缩写,是Java语言访问数据库的标准API,它提供了一套标准的Java接口,用于访问各种关系型数据库系统。本文将介绍如何使用JDBC实现图书馆借阅系统。 步骤 1. 加载数据库驱动 为了使用JDBC访问数据库,我们需要先加载数据库驱动。在这里以MySQL数据库为…

    Java 2023年6月16日
    00
  • SpringBoot之LogBack配置详解

    SpringBoot之LogBack配置详解 1. 前言 LogBack是一款优秀的日志框架,与Log4j类似,但在性能方面更优秀。SpringBoot默认使用Logback来做日志框架,通过使用Logback我们可以很方便地对日志进行管理和查看。 本文主要介绍SpringBoot如何进行LogBack的配置,并集中介绍一系列常用的LogBack配置方法。 …

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