Java在长字符串中查找短字符串的实现多种方法

下面我会详细讲解Java在长字符串中查找短字符串的实现多种方法。

目录

需求背景

在Java程序中处理长字符串时,经常需要进行短字符串的查找。例如,在字符串中查找单词、检查字符串中是否包含某段字符等等。传统的查找方式可能会带来性能上的问题,本文将介绍一些优化的字符串查找方式。

传统字符串查找方式

在介绍优化的字符串查找方式之前,先来看一下传统的字符串查找方式。

String类的indexOf方法

String类提供了indexOf方法来查找一个子串在目标字符串中第一次出现的位置。例如:

String str = "Hello, world!";
int index = str.indexOf("world");
System.out.println(index); // 输出:7

此处查找子串"world"在目标字符串中第一次出现的位置,返回结果为7。

但是,如果需要连续查找多个短字符串,每次调用indexOf方法都需要从头开始扫描目标字符串,这会降低查找效率。

Pattern类的matcher方法

Java提供了正则表达式来进行更为灵活的字符串匹配。Pattern类的matcher方法可以用来实现字符串的正则匹配。例如:

String str = "Hello, world!";
Pattern pattern = Pattern.compile("world");
Matcher matcher = pattern.matcher(str);
if (matcher.find()) {
    int index = matcher.start();
    System.out.println(index); // 输出:7
}

此处使用正则表达式"world"来查找目标字符串中第一次出现的位置。Matcher类中的find方法用于查找下一个匹配项,如果匹配到,则返回true,否则返回false。在查找到匹配项后,可以使用Matcher类的start方法获取匹配项在目标字符串中的起始位置。使用Pattern类和Matcher类进行字符串查找可以实现更为灵活的匹配操作,但是也会带来性能上的降低。

优化的字符串查找方式

针对传统字符串查找方式的性能问题,可以采用优化的字符串查找方式。本节将介绍两种常用的字符串查找算法:Boyer-Moore算法和KMP算法。

Boyer-Moore算法

Boyer-Moore算法是一种高效的字符串查找算法,其核心思想是利用匹配失败时的信息,将待匹配的字符串向右跳过尽可能多的字符,从而提高匹配效率。该算法主要包含两个步骤:

  1. 预处理:根据目标字符串构建坏字符表和好后缀表。
  2. 匹配:从文本串的右端开始匹配,不断跳过无用字符,直到找到匹配项或到达文本串的左端。

Boyer-Moore算法的预处理过程需要对目标字符串进行扫描,因此需要预处理的时间复杂度为O(m + k),其中m为字符串长度,k为字符集大小。字符串的查找时间复杂度为O(n),其中n为文本串长度。

下面是一个使用Boyer-Moore算法进行字符串查找的例子:

public static int boyerMooreStringMatch(String str, String pattern) {
    if (str == null || pattern == null) {
        return -1;
    }
    int n = str.length();
    int m = pattern.length();
    if (n < m) {
        return -1;
    }
    int[] badChar = getBadChar(pattern);
    int[] suffix = getGoodSuffix(pattern);
    int i = m - 1;
    int j = m - 1;
    while (i < n && j >= 0) {
        if (str.charAt(i) == pattern.charAt(j)) {
            i--;
            j--;
        } else {
            i = i + Math.max(j - badChar[str.charAt(i)], suffix[j + 1]);
            j = m - 1;
        }
    }
    if (j == -1) {
        return i + 1;
    } else {
        return -1;
    }
}

private static int[] getBadChar(String pattern) {
    int k = 256;
    int m = pattern.length();
    int[] badChar = new int[k];
    for (int i = 0; i < k; i++) {
        badChar[i] = m;
    }
    for (int i = 0; i < m - 1; i++) {
        badChar[pattern.charAt(i)] = m - 1 - i;
    }
    return badChar;
}

private static int[] getGoodSuffix(String pattern) {
    int m = pattern.length();
    int[] suffix = new int[m + 1];
    suffix[m] = m;
    int j = m;
    for (int i = m - 1; i >= 0; i--) {
        while (j <= m && pattern.charAt(i) != pattern.charAt(j - 1)) {
            if (suffix[j] == 0) {
                suffix[j] = j - i - 1;
            }
            j = suffix[j];
        }
        j--;
        suffix[i] = j;
    }
    return suffix;
}

KMP算法

KMP算法(Knuth-Morris-Pratt算法)是另一种高效的字符串查找算法,其核心思想是利用已经匹配过的信息,在匹配失败时尽量减少重复操作,从而提高匹配效率。该算法主要包括两个步骤:

  1. 预处理:根据目标字符串构建next数组,记录每个位置在匹配失败时需要跳过的字符数。
  2. 匹配:从文本串的左端开始匹配,不断跳过无用字符,直到找到匹配项或到达文本串的右端。

KMP算法的预处理过程需要对目标字符串进行扫描,因此需要预处理的时间复杂度为O(m),其中m为字符串长度。字符串的查找时间复杂度为O(n),其中n为文本串长度。

下面是一个使用KMP算法进行字符串查找的例子:

public static int kmpStringMatch(String str, String pattern) {
    if (str == null || pattern == null) {
        return -1;
    }
    int n = str.length();
    int m = pattern.length();
    if (n < m) {
        return -1;
    }
    int[] next = getNext(pattern);
    int i = 0;
    int j = 0;
    while (i < n && j < m) {
        if (j == -1 || str.charAt(i) == pattern.charAt(j)) {
            i++;
            j++;
        } else {
            j = next[j];
        }
    }
    if (j == m) {
        return i - m;
    } else {
        return -1;
    }
}

private static int[] getNext(String pattern) {
    int j = 0;
    int k = -1;
    int m = pattern.length();
    int[] next = new int[m + 1];
    next[0] = -1;
    while (j < m) {
        if (k == -1 || pattern.charAt(j) == pattern.charAt(k)) {
            j++;
            k++;
            next[j] = k;
        } else {
            k = next[k];
        }
    }
    return next;
}

总结

本文介绍了Java中在长字符串中查找短字符串的实现多种方法,包括传统的字符串查找方式和优化的字符串查找方式。传统的字符串查找方式包括String类的indexOf方法和Pattern类的matcher方法,优化的字符串查找方式包括Boyer-Moore算法和KMP算法。在实际应用中,可以根据具体需求选择合适的字符串查找方式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java在长字符串中查找短字符串的实现多种方法 - Python技术站

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

相关文章

  • Java初学者常问的问题(推荐)

    Java初学者常问的问题(推荐) 1. Java是什么?为什么要学习Java? Java是一种跨平台的面向对象编程语言,在计算机科学领域中应用广泛。学习Java可以让你掌握面向对象编程的基础概念,这对于日后的编程工作非常有帮助。Java也是许多大型企业和开源项目中常用的编程语言之一,掌握Java可以让你获得更多的就业机会。 2. Java有哪些基础概念? J…

    Java 2023年5月23日
    00
  • 图解Java经典算法冒泡选择插入希尔排序的原理与实现

    图解Java经典算法冒泡选择插入希尔排序的原理与实现 什么是排序算法? 排序算法是计算机科学中的一类基本算法,它将一个乱序的数据序列按照一定的规则重新排列,使得排序后的序列满足特定的要求。 常见的排序方法包括冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序等。 冒泡排序的原理和实现 冒泡排序是一种简单的排序算法,其基本思想是从小到大依次比较相邻的两…

    Java 2023年5月19日
    00
  • JSP Spring ApplicationContext的国际化支持

    JSP Spring ApplicationContext的国际化支持是一种让应用程序可以在不修改源代码的情况下,动态切换不同语言版本的功能。下面就详细讲解一下该功能的实现步骤: 第一步:准备资源文件 在项目的src/main/resources目录下创建多个.properties文件,每个文件对应一个语言版本。例如,可以创建messages.propert…

    Java 2023年6月15日
    00
  • 微信小程序实现电子签名功能

    下面详细讲解“微信小程序实现电子签名功能”的完整攻略。 1. 电子签名功能介绍 电子签名是指在电子文档、电子表格等电子化的文件上,用特殊的电子签名技术来确认文件的真实性、完整性、不可抵赖性以及签署人身份的唯一性。在企业、政府等机构中广泛使用,实现了纸质文件的电子化处理,提高了效率和安全性。 2. 实现电子签名的基本原理 实现电子签名的基本原理是通过对签名人的…

    Java 2023年5月30日
    00
  • 一天吃透Redis面试八股文

    Redis连环40问,绝对够全! Redis是什么? Redis(Remote Dictionary Server)是一个使用 C 语言编写的,高性能非关系型的键值对数据库。与传统数据库不同的是,Redis 的数据是存在内存中的,所以读写速度非常快,被广泛应用于缓存方向。Redis可以将数据写入磁盘中,保证了数据的安全不丢失,而且Redis的操作是原子性的。…

    Java 2023年5月1日
    00
  • 关于logBack配置日志文件及编码配置的问题

    关于logBack配置日志文件及编码配置的完整攻略如下: 1. 导入Logback依赖 首先需要在项目中导入Logback依赖,可以在pom.xml中进行配置: <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic&…

    Java 2023年5月20日
    00
  • MySQL为例讲解JDBC数据库连接步骤

    MySQL为例讲解JDBC数据库连接步骤 JDBC简介 JDBC(Java Database Connectivity)是一种Java语言中访问数据库的API(Application Programming Interface)。 JDBC可以让Java程序连接到各种关系型数据库,进行数据的读取、写入操作等。JDBC的设计目标是使Java程序员从不同的关系型…

    Java 2023年5月20日
    00
  • 使用IDEA搭建SSM框架的详细教程(spring + springMVC +MyBatis)

    使用IDEA搭建SSM框架的详细教程 简介 SSM框架是目前Java Web开发中最常用的框架之一,它由Spring、SpringMVC和MyBatis三个框架组成,可以很好地解决Java Web开发中的各种问题。本文将详细介绍如何使用IDEA搭建SSM框架,并提供两个示例说明。 环境准备 在开始之前,需要确保以下环境已经准备好: JDK 1.8以上版本 M…

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