Java中字符串匹配算法的实现函数
在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算法更稳定。
