📅  最后修改于: 2023-12-03 15:39:02.123000             🧑  作者: Mango
在文本处理中,经常会涉及到对给定字符串中子字符串的频率进行计算的需求。本文将介绍如何使用C++语言实现对字符串中子字符串的频率计算。
给定一个字符串str和一个子字符串substr,要求计算子字符串在给定字符串中出现的次数。例如,如果给定字符串是"aaabbaa",子字符串是"aa",那么子字符串在给定字符串中出现的次数为2。
最朴素的方法是从给定字符串的首字符开始,挨个比较该位置开始的子字符串和目标子字符串是否相同。如果相同,计数器加1,接着继续比较从下一个字符开始的子字符串,以此类推。该实现的时间复杂度为O(N*M),其中N是给定字符串的长度,M是子字符串的长度。
int countSubstr(string str, string substr) {
int count = 0;
for (int i = 0; i <= str.length() - substr.length(); i++) {
bool isMatched = true;
for (int j = 0; j < substr.length(); j++) {
if (str[i+j] != substr[j]) {
isMatched = false;
break;
}
}
if (isMatched) {
count++;
}
}
return count;
}
KMP算法是一种高效的字符串匹配算法,在这里,我们可以将其用于求子字符串的频率。该算法的时间复杂度为O(N+M),其中N是给定字符串的长度,M是子字符串的长度。相比于第一种方法,KMP算法的优势更加明显。
int countSubstr(string str, string substr) {
int count = 0;
int n = str.length(), m = substr.length();
vector<int> next(m + 1, 0);
for (int i = 1, j = 0; i < m; i++) {
while (j && substr[i] != substr[j]) {
j = next[j];
}
if (substr[i] == substr[j]) {
j++;
}
next[i+1] = j;
}
for (int i = 0, j = 0; i < n; i++) {
while (j && str[i] != substr[j]) {
j = next[j];
}
if (str[i] == substr[j]) {
j++;
}
if (j == m) {
count++;
j = next[j];
}
}
return count;
}
本文介绍了两种方法来解决字符串中子字符串的频率计算问题。方法一是最朴素的暴力枚举,时间复杂度为O(N*M)。方法二是KMP算法,时间复杂度为O(N+M),相比之下更加高效。需要注意的是,KMP算法需要预处理出子字符串的next数组,这会增加一些额外的时间和空间开销。