编写一个程序exp4-6.cpp,利用KMP算法求子串1在主申s中不重叠出现的次数,并以s=”aaabbdaabbde”,t=”aabbd”为例(答案为2)显示匹配过程。
时间: 2024-11-13 11:40:01 浏览: 10
首先,让我解释一下KMP(Knuth-Morris-Pratt)算法。这是一种用于字符串匹配的有效算法,它通过预处理模式串来避免在搜索过程中不必要的回溯。当需要查找子串`t`在主串`s`中出现的次数,且要求不重叠时,KMP算法能够有效地找到所有匹配的位置。
下面是一个简单的C++程序示例,展示了如何使用KMP算法实现这个功能:
```cpp
#include <iostream>
#include <vector>
// 计算最长公共前缀函数
std::vector<int> compute_lps(const std::string& pattern) {
int len = pattern.size();
std::vector<int> lps(len);
for (int i = 1; i < len; ++i) {
while (lps[i - 1] != 0 && pattern[lps[i - 1]] != pattern[i]) {
lps[i] = lps[i - 1];
}
else if (pattern[lps[i - 1]] == pattern[i]) {
lps[i]++;
}
}
return lps;
}
// KMP匹配函数
int kmp_search(const std::string& text, const std::string& pattern) {
int n = text.size(), m = pattern.size();
std::vector<int> lps = compute_lps(pattern);
int count = 0, i = 0, j = 0;
while (i < n) {
if (j == m || (text[i] == pattern[j])) {
i++;
j++;
count++;
}
else {
if (j != 0)
j = lps[j - 1];
else
i++;
}
}
return count;
}
int main() {
std::string s = "aaabbdaabbde";
std::string t = "aabbd";
int matches = kmp_search(s, t);
std::cout << "子串 " << t << " 在主串 " << s << " 中不重叠出现的次数为: " << matches << std::endl;
// 显示匹配过程
std::cout << "匹配过程:\n";
for (int i = 0; i <= s.size() - t.size(); ) {
if (s.substr(i, t.size()) == t) {
std::cout << "在位置 " << i << ": " << t << "\n";
i += t.size();
} else {
i += 1;
}
}
return 0;
}
```
当你运行这个程序,它会输出结果 `子串 aabbd 在主串 aaabbdaabbde 中不重叠出现的次数为: 2`,并展示匹配的具体位置。
阅读全文