字符串匹配bf算法与KMP算法
时间: 2025-01-07 14:43:29 浏览: 4
### BF算法与KMP算法的实现方式
#### BF算法
暴力匹配(BF)算法是一种简单的字符串匹配方法。该算法通过逐一比较主串和模式串中的字符来查找匹配项。具体来说,在每次不匹配的情况下,主串指针会回溯到上一次匹配起始位置之后的一个新位置,而模式串则重新从头开始匹配[^2]。
```java
public boolean bf(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 && pattern.charAt(j) == text.charAt(i + j); ++j);
if (j == m) return true; // 找到了完整的匹配
}
return false;
}
```
#### KMP算法
相比之下,KMP算法利用了部分匹配的信息以避免不必要的重复扫描。当遇到不匹配的情况时,不是简单地将主串指针向前推进一位并重置模式串指针至开头,而是依据预先计算好的`next`数组调整模式串的位置继续尝试匹配。这样可以显著减少比较次数,提高效率[^3]。
```java
public class KMP {
private static final void computeLPSArray(char[] pat, int M, int lps[]) {
int length = 0; // 长度 of the previous longest prefix suffix
int i = 1;
lps[0] = 0; // LPS 的第一个值总是 0
while (i < M) {
if (pat[i] == pat[length]) {
length++;
lps[i] = length;
i++;
} else {
if (length != 0) {
length = lps[length - 1];
} else {
lps[i] = 0;
i++;
}
}
}
}
public static int KMPSearch(String txt, String pat) {
int N = txt.length(), M = pat.length();
char T[] = txt.toCharArray();
char P[] = pat.toCharArray();
int lps[] = new int[M];
/* Preprocess the pattern */
computeLPSArray(P, M, lps);
int i = 0; // index for txt[]
int j = 0; // index for pat[]
while ((N - i) >= (M - j)) {
if (P[j] == T[i]) {
j++;
i++;
}
if (j == M) {
System.out.println("Found pattern at index " + (i-j));
j = lps[j-1];
}
// mismatch after j matches
else if (i < N && P[j] != T[i]) {
// Do not match lps[0..lps[j-1]] characters,
// they will match anyway
if (j != 0)
j = lps[j-1];
else
i = i+1;
}
}
return -1;
}
}
```
### 性能对比
对于最坏情况下的时间复杂度而言:
- **BF算法**: O(n * m),其中n为主串长度,m为模式串长度。这是因为每当发生失配时,都需要回到之前的状态重新开始比较。
- **KMP算法**: O(n + m),因为预处理阶段构建`next`数组的时间开销是O(m),而在实际搜索过程中每个字符最多只会被访问两次——一次作为主串的一部分,另一次可能是在模式串内参与比较。因此整体性能更优。
阅读全文