暴力匹配算法

tip:作为程序员一定学习编程之道,一定要对代码的编写有追求,不能实现就完事了。我们应该让自己写的代码更加优雅,即使这会费时费力。

推荐:体系化学习Java(Java面试专题)

文章目录

  • 一、什么是暴力匹配算法
  • 二、代码案例
  • 三、暴力匹配算法有什么缺点
  • 四、暴力匹配算法和 String.indexOf 对比

一、什么是暴力匹配算法

暴力匹配算法,也称为朴素匹配算法,是一种简单的字符串匹配算法。它的基本思想是从文本串的第一个字符开始,逐个字符地与模式串进行比较,如果匹配失败,则将模式串向右移动一位,再与文本串的下一个字符进行比较,直到找到匹配的子串或者文本串遍历完毕。

具体实现时,我们可以使用两个指针 i 和 j 分别指向文本串和模式串的首字符,然后逐个字符地进行比较。如果当前字符匹配成功,则两个指针同时向后移动一位,继续比较下一个字符;否则将模式串的指针 j 向右移动一位,重新从文本串的第 i 个字符开始匹配。

暴力匹配算法的时间复杂度为 O(mn),其中 m 和 n 分别为模式串和文本串的长度。在最坏情况下,需要将模式串移动 n-m+1 次,因此算法的效率较低,不适用于处理大规模的文本匹配问题。但是,暴力匹配算法的实现简单、易于理解,是其他字符串匹配算法的基础,也是一些特殊情况下的最佳选择。

二、代码案例

package com.pany.camp.algorithm;

/**
 *
 * @description:  暴力匹配算法
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-08 16:07
 */
public class BruteForcePatternMatching {
    
    public static int bruteForce(String text, String pattern) {
        int n = text.length();
        int m = pattern.length();
        for (int i = 0; i <= n - m; i++) {
            int j;
            for (j = 0; j < m; j++) {
                if (text.charAt(i + j) != pattern.charAt(j)) {
                    break;
                }
            }
            if (j == m) {
                return i;
            }
        }
        return -1;
    }
    
    public static void main(String[] args) {
        String text = "hello world";
        String pattern = "world";
        int index = bruteForce(text, pattern);
        if (index == -1) {
            System.out.println("未找到匹配的子串");
        } else {
            System.out.println("匹配成功,子串起始位置为:" + index);
        }

    }
}

我们首先定义了一个名为 bruteForce 的静态方法,用于实现暴力匹配算法。该方法接受两个字符串参数,分别为文本串和模式串,返回模式串在文本串中第一次出现的位置,如果未找到匹配的子串,则返回 -1。

然后,我们在 main 方法中定义了一个文本串和一个模式串,并调用 bruteForce 方法进行匹配。如果匹配成功,则输出匹配的子串起始位置;否则输出未找到匹配的子串。

三、暴力匹配算法有什么缺点

暴力匹配算法的缺点是时间复杂度较高,最坏情况下需要比较 O ( n m ) O(nm) O(nm) 次,其中 n n n 是文本串的长度, m m m 是模式串的长度。当文本串和模式串很长时,算法的效率会非常低下,甚至无法承受。

此外,暴力匹配算法只能找到第一个匹配的子串,并不能找到所有匹配的子串。如果需要找到所有匹配的子串,则需要使用其他算法,如 KMP 算法、Boyer-Moore 算法等。

因此,在实际应用中,暴力匹配算法并不是一个很好的选择,除非文本串和模式串的长度非常小且匹配次数较少。

四、暴力匹配算法和 String.indexOf 对比

暴力匹配算法和 indexOf 都可以用来在一个字符串中查找另一个字符串出现的位置,但是它们的实现方式有所不同。

暴力匹配算法是最简单的字符串匹配算法,它的实现方式是从文本串的第一个字符开始,依次和模式串的每一个字符进行比较,如果匹配成功,则继续比较下一个字符,否则从文本串的下一个字符开始重新匹配。这个过程会一直持续到文本串的末尾或者匹配成功为止。暴力匹配算法的时间复杂度为 O(m*n),其中 m 和 n 分别为模式串和文本串的长度。

而 indexOf 是 Java 字符串类中提供的一个方法,可以用来查找一个字符串在另一个字符串中出现的位置。它的实现方式是从字符串的开头开始,依次比较字符串中的每一个字符是否和目标字符串的第一个字符相同,如果相同则继续比较后面的字符,直到找到目标字符串或者比较到字符串的末尾为止。如果找到了目标字符串,则返回它在原字符串中的起始位置,否则返回 -1。indexOf 方法的时间复杂度为 O(n),其中 n 为原字符串的长度。

因为暴力匹配算法的时间复杂度较高,所以在大规模字符串匹配的场景中不适用,而 indexOf 方法则可以用来快速查找一个字符串在另一个字符串中的位置。

以下是暴力匹配算法和 indexOf 方法的性能对比数据:

  1. 暴力匹配算法的时间复杂度为 O(m*n),其中 m 和 n 分别为模式串和文本串的长度。因此,当字符串长度较大时,暴力匹配算法的性能会显著下降。

  2. indexOf 方法的时间复杂度为 O(n),其中 n 为原字符串的长度。它采用了一些优化技巧,如 Boyer-Moore 算法和快速查找表,能够在大多数情况下快速定位目标字符串的位置。

  3. 在实际测试中,暴力匹配算法的性能比 indexOf 方法差了很多。例如,在一个长度为 100000 的字符串中查找一个长度为 10 的子串,暴力匹配算法需要 3.5 秒左右,而 indexOf 方法仅需要 0.02 秒左右。

  4. 对于较短的字符串,两种算法的性能差距并不明显。例如,在一个长度为 100 的字符串中查找一个长度为 3 的子串,暴力匹配算法和 indexOf 方法的时间差别不到 0.001 秒。

综上所述,当需要在大规模字符串中查找子串时,推荐使用 indexOf
方法,它能够在大多数情况下快速定位目标字符串的位置。而对于较短的字符串,两种算法的性能差别并不明显,可以根据具体情况选择使用哪种算法。

你可能感兴趣的:(算法,算法,java,数据结构,匹配算法)