题解
子串个数
1 条题解
-
0
解题思路
“子串”的意思是:b 在 a 里连续的一段和它完全一样,那么 b 就是 a 的子串。题目问的是 a 里一共能找出多少个 b。
注意!字符串 a 和 b 都可能包含空格,所以不能用
cin >>读(它遇到空格就停了),要用getline一次读一整行。数子串的办法:
- 用
find在 a 里找 b,找到的位置记下来,答案加 1; - 从找到位置的下一个位置继续找,这样像
aaaa里找aa这种重叠的情况也能数到:- 第 1 个
aa在第 0~1 位; - 再从第 1 位开始找,第 2 个
aa在第 1~2 位; - 再从第 2 位开始找,第 3 个
aa在第 2~3 位; - 一共 3 个。
- 第 1 个
find找不到的时候会返回一个特殊值string::npos,表示“不存在”,这时就结束循环。
用样例验证:a=
welcome to my hometown!,b=me。在welcome里找到第 1 个me,在hometown里找到第 2 个me,一共 2 个,和样例一致。参考代码
// P4551 子串个数:统计b在a中出现的次数(允许重叠) #include <iostream> #include <string> using namespace std; int main() { string a, b; getline(cin, a); // 第1行可能含空格,用getline读整行 getline(cin, b); // 第2行可能含空格,同样用getline int cnt = 0; int pos = 0; // 反复从a中查找b,找到一次答案加1,再从下一个位置继续找 while (true) { pos = a.find(b, pos); if (pos == string::npos) break; // 找不到了就结束 cnt++; pos++; // 从下一位置继续,允许重叠统计 } cout << cnt << endl; return 0; }复杂度分析
- a 的长度不超过 1000,b 不超过 20。每次
find最多比较 O(a 的长度 × b 的长度) 次,最多找 O(a 的长度) 次。 - 总时间复杂度 O(n × m),n≤1000、m≤20,非常快;
- 空间复杂度 O(1),只用了两个字符串变量。
- 用
- 1