如何使用C++编程语言来实现KMP(Knuth-Morris-Pratt)算法进行字符串模式匹配?
时间: 2024-11-30 16:18:34 浏览: 5
KMP算法是一种高效的字符串匹配算法,用于在一个文本串中查找指定模式串的所有出现位置。在C++中实现KMP算法,你需要准备两个关键部分:模式串的前缀函数计算以及实际的匹配过程。
1. **计算前缀函数**:
- 创建一个`next`数组,长度等于模式串的长度。`next[i]`表示在发生错误时,模式串应从当前位置`i`跳到的位置,使得匹配能继续进行。
- 通过以下步骤计算`next`数组:
- 初始化`next[0] = 0`,因为一个空的前缀不可能导致失败。
- 从`i = 1`开始遍历模式串,如果`pattern[i] == pattern[next[i-1]]`,则`next[i] = next[i-1]+1`;否则,尝试从更大的跳跃值开始找到最长的相等子串,即`j = next[next[i-1]]`,然后`next[i] = j + 1`,直到找到一个大于0的`j`或者`pattern[i]`和`pattern[j+1]`都不相等为止。
2. **字符串匹配**:
- 定义两个指针`text_ptr`和`pattern_ptr`,分别指向文本串和模式串的起始位置。
- 当`text_ptr`和`pattern_ptr`都有效(即都在各自的串内)且`text[text_ptr]`等于`pattern[pattern_ptr]`时,同时增加两个指针。
- 如果不相等,首先检查`pattern_ptr`是否可以用`next[pattern_ptr]`进行跳跃,若可以则移动`pattern_ptr`;若不能,则只移动`text_ptr`,因为它无法找到正确的匹配。
以下是简单的C++代码示例:
```cpp
#include <vector>
using namespace std;
vector<int> getPrefixFunction(const string& pattern) {
int len = pattern.size();
vector<int> next(len);
for (int i = 1, j = 0; i < len; ++i) {
while (j > 0 && pattern[i] != pattern[j])
j = next[j - 1];
if (pattern[i] == pattern[j])
++j;
next[i] = j;
}
return next;
}
bool KMPMatch(const string& text, const string& pattern, vector<int>& prefix) {
int text_len = text.length(), pattern_len = pattern.length();
int text_ptr = 0, pattern_ptr = 0;
while (text_ptr < text_len && pattern_ptr < pattern_len) {
if (text[text_ptr] == pattern[pattern_ptr])
text_ptr++, pattern_ptr++;
else if (pattern_ptr > 0)
pattern_ptr = prefix[pattern_ptr - 1];
else
text_ptr++;
}
return pattern_ptr == pattern_len;
}
int main() {
string text = "ABABCABADCAB";
string pattern = "ABCD";
vector<int> prefix = getPrefixFunction(pattern);
cout << "Pattern found in the text? : " << (KMPMatch(text, pattern, prefix) ? "Yes" : "No") << endl;
return 0;
}
```
阅读全文