设主串为S,模式为T,写出kmp算法的匹配过程 主串为''aababcaabaabccb'' 模式为''aabaabc 用c++写出
时间: 2024-10-24 07:11:23 浏览: 26
如何用KMP字符串匹配算法求出主串中所包含模式串的总个数
KMP(Knuth-Pratt)算法是一种用于字符串匹配的高效算法,它通过预处理模式串来避免不必要的字符比较,提高了查找效率。假设主串为 `S` 和模式为 `T`,我们使用 KMP 算法的过程可以这样描述:
1. **构建失配函数**(部分匹配表):对模式串 `T`,从第二个字符开始,对于每个位置 i,检查其前面的字符序列 `T[0...i-1]` 是否等于 `T[1...i]`,如果不是,则计算最长公共前后缀的长度,即上一个位置 j(j<i)使得 `T[j+1]=T[i]`。记录这个长度,存储在一个数组 `lps[]` 中。
对于模式 "aabaabc",失配函数 `lps` 会是 `[0, 0, 1, 2, 0, 0, 3]`,因为 "aaba" 和 "aa" 的前缀一样长,之后的 "b" 和 "bb" 同样匹配,然后 "a" 与 "ab" 不匹配,所以 "aba" 和 "ab" 的前缀匹配长度是 0,以此类推。
2. **匹配过程**:从主串 `S` 开始,当前索引为 `i = 0`,模式索引为 `j = 0`。如果 `S[i]` 等于 `T[j]`,则同时将 `i` 和 `j` 自增;否则,如果 `j` 不为 0,则查看 `lps[j]` 是否大于 0,表示跳过当前位置之前的部分,更新 `j` 为 `j - lps[j]`;如果 `j` 为 0,则说明未找到匹配,向右移动主串索引 `i`,直到找到匹配或者 `i < len(S)`。
对于主串 "aababcaabaabccb" 和模式 "aabaabc",初始匹配,但遇到第一个 "b",根据失配函数我们知道可以跳过一个 "a",继续搜索。
3. **返回结果**:当找到完整的匹配或者遍历完主串后,如果没有找到完整的匹配,那么 `j` 就是最后一个成功匹配的位置加一。
由于这是文字描述,以下是 C++ 代码片段演示如何应用 KMP 算法:
```cpp
#include <vector>
std::vector<int> getLPS(const std::string& pattern) {
int n = pattern.size();
std::vector<int> lps(n);
for (int i = 1; i < n; ++i) {
int j = lps[i - 1];
while (j > 0 && pattern[i] != pattern[j]) {
j = lps[j - 1];
}
if (pattern[i] == pattern[j]) {
++j;
}
lps[i] = j;
}
return lps;
}
bool kmpMatch(const std::string& text, const std::string& pattern) {
auto lps = getLPS(pattern);
int i = 0, j = 0;
while (i < text.length()) {
if (text[i] == pattern[j]) {
++i;
++j;
} else if (j > 0) {
j = lps[j - 1];
} else {
++i;
}
if (j == pattern.length()) {
// 找到了匹配
return true;
}
}
return false;
}
int main() {
std::string s = "aababcaabaabccb";
std::string t = "aabaabc";
if (kmpMatch(s, t)) {
std::cout << "Pattern found in the string." << std::endl;
} else {
std::cout << "Pattern not found in the string." << std::endl;
}
return 0;
}
```
阅读全文