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日

相关文章

  • Java四种常用线程池的详细介绍

    Java四种常用线程池的详细介绍 线程池的作用 在高并发处理场景下,线程的创建、销毁以及上下文切换会消耗大量的CPU和内存资源,从而影响系统的性能。为了解决这个问题,Java提供了线程池来管理线程,使得线程的创建、销毁、复用和调度都可以由线程池来完成,从而减少线程的创建和销毁带来的开销,提高系统的并发处理能力。 Java中线程池的实现 Java中的线程池是通…

    Java 2023年5月18日
    00
  • Java代码审计的一些基础知识你知道吗

    Java代码审计的一些基础知识你知道吗 什么是Java代码审计? Java代码审计是指对Java应用程序中的源代码进行检查、识别和评估安全漏洞的过程。此过程旨在识别开发中可能导致安全漏洞的编程错误或不良实践。它可以帮助开发人员找到这些漏洞并修复它们,提高软件的安全性。 Java代码审计的步骤 阅读和理解代码。 理解应用程序的功能并确定期望行为。 寻找不安全的…

    Java 2023年5月23日
    00
  • Java中使用Properties配置文件的简单方法

    下面是详细的Java中使用Properties配置文件的攻略。 1. Properties配置文件介绍 Properties类是Java提供的一个工具类,可以方便地读取和写入配置文件。使用Properties可以将配置信息保存在文件中,比如常见的应用程序的配置信息。Properties文件是一种常见的配置文件格式,可以用键值对(key=value)的方式保存…

    Java 2023年5月20日
    00
  • Java如何将若干时间区间进行合并的方法步骤

    Java如何将若干时间区间进行合并的方法步骤: 1.首先需要将若干时间区间存储到一个List集合中。时间区间可以使用Java中的Date或LocalDateTime对象来表示,或者使用字符串表示,需要转换为相应的日期对象。 2.对这个区间集合进行排序,按照开始时间升序排序。 3.新建一个结果集合,将第一个区间加入结果集合,用一个current指针指向结果集合…

    Java 2023年5月20日
    00
  • JSP struts2 url传参中文乱码解决办法

    JSP struts2 url传参中文乱码解决办法 问题描述 在使用 JSP 和 Struts2 构建 Web 应用程序时,我们常常需要通过 URL 传参。但是,如果参数中包含中文等非 ASCII 字符,就会出现乱码的问题。这是因为浏览器默认使用的是 ISO-8859-1 编码方式,而中文需要使用 UTF-8 编码,两种编码方式不同,导致乱码的出现。 解决办…

    Java 2023年6月15日
    00
  • Springboot配置security basic path无效解决方案

    针对“Springboot配置security basic path无效解决方案”,以下是完整的攻略: 1. 问题描述 当我们在Spring Boot项目中将Spring Security集成进来时,有时候会发现配置的basic path无效,即虽然配置了basic path,但在请求时仍然需要登录验证,这种情况该怎么解决呢? 2. 解决方案 2.1 配置W…

    Java 2023年5月20日
    00
  • Java并行处理的实现

    Java并行处理的实现攻略 在Java中实现并行处理可以提高代码的性能,让代码的运行更快。本文将介绍Java中并行处理的实现攻略。 并行处理的概念和原理 并行处理是指多个任务同时执行,相互之间不受影响,可以提高代码的运行效率。Java中可以使用多线程实现并行处理。多线程是指同时运行多个线程,每个线程都独立运行,并且可以访问共享变量。Java中的线程是通过ja…

    Java 2023年5月18日
    00
  • Java 8中 Stream小知识小技巧方法梳理

    Java 8中 Stream小知识小技巧方法梳理 什么是Stream Stream是Java 8中的新特性,它能够处理大批量的数据,并且可以并发处理数据,极大地提升了Java程序的性能。Stream与Java中的集合类(如List、Set、Map等)不同之处在于,它并不直接存储数据,而是对数据进行处理。 Stream的原理 Stream中的数据是以流的方式进…

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