文章目录
- 暴力匹配(Brute Force Matching):
public class BruteForceMatching {
public static int search(String text, String pattern) {
int textLength = text.length();
int patternLength = pattern.length();
for (int i = 0; i <= textLength - patternLength; i++) {
int j;
for (j = 0; j < patternLength; j++) {
if (text.charAt(i + j) != pattern.charAt(j)) {
break;
}
}
if (j == patternLength) {
return i; // 找到了匹配
}
}
return -1; // 没有找到匹配
}
public static void main(String[] args) {
String text = "Hello, world!";
String pattern = "world";
int index = search(text, pattern);
if (index != -1) {
System.out.println("Pattern found at index: " + index);
} else {
System.out.println("Pattern not found.");
}
}
}
- KMP算法(Knuth-Morris-Pratt Algorithm):
KMP算法的实现相对复杂,因为它需要预处理模式字符串以创建一个“部分匹配表”或“失败函数”。以下是KMP算法的一个简化实现:
public class KMPAlgorithm {
private static int[] computeLPSArray(String pattern, int M, int lps[]) {
int len = 0;
int i = 1;
lps[0] = 0; // lps[0] is always 0
while (i < M) {
if (pattern.charAt(i) == pattern.charAt(len)) {
len++;
lps[i] = len;
i++;
} else {
if (len != 0) {
len = lps[len - 1];
} else {
lps[i] = len;
i++;
}
}
}
}
public static int KMPSearch(String text, String pattern) {
int M = pattern.length();
int N = text.length();
int[] lps = new int[M];
computeLPSArray(pattern, M, lps);
int j = 0; // index for pattern[]
int i = 0; // index for text[]
while (i < N) {
if (pattern.charAt(j) == text.charAt(i)) {
j++;
i++;
}
if (j == M) {
return i - j; // 匹配成功,返回位置
j = lps[j - 1];
} else if (i < N && pattern.charAt(j) != text.charAt(i)) {
if (j != 0)
j = lps[j - 1];
else
i = i + 1;
}
}
return -1; // 匹配失败
}
public static void main(String[] args) {
String text = "ABABDABACDABABCABAB";
String pattern = "ABABCABAB";
int index = KMPSearch(text, pattern);
if (index != -1) {
System.out.println("Pattern found at index: " + index);
} else {
System.out.println("Pattern not found.");
}
}
}
- Boyer-Moore算法:
Boyer-Moore算法的实现通常比KMP更复杂,因为它使用了一种从右向左比较的策略,并基于坏字符和好后缀规则进行跳转。以下是Boyer-Moore算法的一个简化版本:
当然,我们可以继续实现Boyer-Moore算法的基于坏字符的简化版本。下面是一个完成后的示例代码:
import java.util.Arrays;
public class BoyerMooreAlgorithm {
// 假设这里只实现了基于坏字符的简化版本
public static int boyerMooreSearch(String text, String pattern) {
if (pattern.isEmpty()) {
return 0; // 空模式在任何位置都匹配
}
int[] badChar = new int[256]; // 假设ASCII字符集
Arrays.fill(badChar, -1);
// 预处理坏字符表
for (int i = 0; i < pattern.length(); i++) {
badChar[pattern.charAt(i)] = i;
}
int n = text.length();
int m = pattern.length();
int skip;
// 从文本末尾开始搜索
for (int i = n - 1; i >= 0; i -= skip) {
skip = 0; // 重置skip
// 从右向左比较
for (int j = m - 1; j >= 0; j--) {
if (i - j < 0 || pattern.charAt(j) != text.charAt(i - j)) {
// 不匹配,根据坏字符表进行跳转
skip = Math.max(1, j - badChar[text.charAt(i - j)]);
break;
}
}
// 如果j到达-1,则表示匹配成功
if (j == -1) {
return i - m + 1; // 返回匹配的起始位置
}
}
// 没有找到匹配项
return -1;
}
public static void main(String[] args) {
String text = "HERE IS A SIMPLE EXAMPLE TEXT";
String pattern = "SIMPLE";
int index = boyerMooreSearch(text, pattern);
if (index != -1) {
System.out.println("Pattern found at index: " + index);
} else {
System.out.println("Pattern not found.");
}
}
}
在上面的代码中,我们首先定义了一个大小为256的badChar
数组来存储坏字符表。然后,我们遍历模式字符串来填充这个表,使得badChar[ch]
存储的是字符ch
在模式字符串中最后出现的位置(如果不存在则为-1)。
在搜索过程中,我们从文本字符串的末尾开始,从右向左与模式字符串进行比较。如果遇到不匹配的字符,我们根据坏字符表来确定下一步应该跳过的字符数。
如果整个模式字符串都与文本字符串的某个子串匹配,那么我们就返回该子串的起始位置。如果搜索完整个文本字符串都没有找到匹配项,我们就返回-1表示未找到。