欢迎访问宙启技术站
智能推送

Java中字符串匹配算法的实现函数

发布时间:2023-06-19 11:30:20

在Java中,字符串匹配算法的实现函数可以有很多种。下面介绍常见的三种字符串匹配算法的实现函数并进行分析。

1. 暴力匹配算法

暴力匹配算法是最简单也是最暴力的字符串匹配算法。它的思想是从文本串的 个字符开始,逐个字符地与模式串进行比较,直到匹配或文本串结束。如果匹配成功,则返回匹配位置;如果匹配失败,则继续在文本串中下一个位置开始匹配。

该算法的代码如下:

public static int bruteMatch(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;

}

该算法的时间复杂度是O(m*n),其中m为模式串的长度,n为文本串的长度。如果模式串和文本串长度相当,则该算法的效率最高,但如果模式串很长而文本串很短,则该算法的效率很低。

2. KMP算法

KMP算法是一种比较高效的字符串匹配算法。其基本思想是在匹配过程中利用已经匹配的信息来指导下一次匹配。具体来说,该算法通过预处理模式串,得到一个next数组,用于指导匹配过程中的跳转。next数组可以在O(m)的时间内预处理完成,匹配过程也可以在O(n)的时间内完成。

该算法的代码如下:

public static int kmpMatch(String text, String pattern) {

    int n = text.length();

    int m = pattern.length();

    int[] next = getNext(pattern);

    int i = 0;

    int j = 0;

    while (i < n && j < m) {

        if (j == -1 || text.charAt(i) == pattern.charAt(j)) {

            i++;

            j++;

        } else {

            j = next[j];

        }

        if (j == m) {

            return i-m;

        }

    }

    return -1;

}

private static int[] getNext(String pattern) {

    int m = pattern.length();

    int[] next = new int[m];

    int i = 0;

    int j = -1;

    next[0] = -1;

    while (i < m - 1) {

        if (j == -1 || pattern.charAt(i) == pattern.charAt(j)) {

            i++;

            j++;

            next[i] = j;

        } else {

            j = next[j];

        }

    }

    return next;

}

该算法的时间复杂度是O(m+n),其中m为模式串的长度,n为文本串的长度。因此,如果模式串很长而文本串很短,该算法效率也很高。

3. Boyer-Moore算法

Boyer-Moore算法是一种基于比较字符的方法进行字符串匹配的算法。其基本思想是从后往前匹配,并且尽量跳过比较,以提高效率。具体来说,该算法通过预处理模式串,得到一个badChar数组和goodSuffix数组,并且根据这两个数组来确定每次匹配和跳过的位置。

该算法的代码如下:

public static int boyerMooreMatch(String text, String pattern) {

    int n = text.length();

    int m = pattern.length();

    int[] badChar = getBadChar(pattern);

    int[] goodSuffix = getGoodSuffix(pattern);

    int i = m - 1;

    int j = m - 1;

    while (i < n && j >= 0) {

        if (text.charAt(i) == pattern.charAt(j)) {

            i--;

            j--;

        } else {

            i += m - 1 - j + Math.max(j - badChar[text.charAt(i)], goodSuffix[j]);

            j = m - 1;

        }

        if (j < 0) {

            return i+1;

        }

    }

    return -1;

}

private static int[] getBadChar(String pattern) {

    int m = pattern.length();

    int[] badChar = new int[256];

    Arrays.fill(badChar, -1);

    for (int i = 0; i < m; i++) {

        badChar[pattern.charAt(i)] = i;

    }

    return badChar;

}

private static int[] getGoodSuffix(String pattern) {

    int m = pattern.length();

    int[] goodSuffix = new int[m];

    Arrays.fill(goodSuffix, -1);

    int[] suffix = new int[m];

    int i = m - 1;

    int j = m - 2;

    suffix[m-1] = m;

    for (int k = m - 2; k >= 0; k--) {

        if (k > j && suffix[k + m - 1 - i] < k - j) {

            suffix[k] = suffix[k + m - 1 - i];

        } else {

            j = Math.min(k, j);

            i = k;

            while (j >= 0 && pattern.charAt(j) == pattern.charAt(j + m - 1 - i)) {

                j--;

            }

            suffix[k] = i - j;

        }

    }

    for (int k = 0; k < m - 1; k++) {

        goodSuffix[k] = m;

    }

    for (int k = m - 1; k >= 0; k--) {

        if (suffix[k] == k + 1) {

            for (int j = 0; j < m - 1 - k; j++) {

                if (goodSuffix[j] == m) {

                    goodSuffix[j] = m - 1 - k;

                }

            }

        }

    }

    for (int k = 0; k < m - 2; k++) {

        goodSuffix[m - 1 - suffix[k]] = m - 1 - k;

    }

    return goodSuffix;

}

该算法的时间复杂度是O(m+n),其中m为模式串的长度,n为文本串的长度。Boyer-Moore算法在实践中比KMP算法效率更高,并且它针对不同的文本串,算法的运行速度比KMP算法更稳定。