出现次数
出现次数
给定一个长度为 的字符串 以及一个长度为 的字符串 。
两个字符串都由小写字母构成。
用 来表示字符串 的子串 。
有 个询问,每个询问给出两个整数 (),请你计算字符串 在 中作为子串出现了多少次。
例如,字符串 abacabadabacaba 中共包含 个子串 ba ,所以 ba 在 abacabadabacaba 中作为子串出现了 次。
输入格式
第一行包含三个整数 。
第二行包含一个长度为 的由小写字母构成的字符串 。
第三行包含一个长度为 的由小写字母构成的字符串 。
接下来 行,每行包含两个整数 。
输出格式
每个询问输出一行答案,一个整数,表示出现次数。
数据范围
前三个测试点满足 。
所有测试点满足 。
输入样例1:
15 2 3 abacabadabacaba ba 1 15 3 4 2 14
输出样例1:
4 0 3
输入样例2:
3 5 2 aaa baaab 1 3 1 1
输出样例2:
0 0
解题思路
这题可以用kmp过,但时间复杂度是,达到级别,能不能过很悬,但最后还是过了。
kmp写法的AC代码如下:
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 const int N = 1010; 6 7 char str1[N], str2[N]; 8 int ne[N]; 9 10 int main() { 11 int n, m, tot; 12 scanf("%d %d %d", &n, &m, &tot); 13 scanf("%s %s", str1 + 1, str2 + 1); 14 15 for (int i = 2, j = 0; i <= m; i++) { 16 while (j && str2[i] != str2[j + 1]) { 17 j = ne[j]; 18 } 19 if (str2[i] == str2[j + 1]) j++; 20 ne[i] = j; 21 } 22 23 while (tot--) { 24 int l, r; 25 scanf("%d %d", &l, &r); 26 27 int ret = 0; 28 for (int i = l, j = 0; i <= r; i++) { 29 while (j && str1[i] != str2[j + 1]) { 30 j = ne[j]; 31 } 32 if (str1[i] == str2[j + 1]) j++; 33 if (j == m) { 34 ret++; 35 j = ne[j]; 36 } 37 } 38 39 printf("%d\n", ret); 40 } 41 42 return 0; 43 }
这里给出一种用前缀和的解法,这种解法完全没想到。前缀和不仅可以求和,还可以统计个数。
对于串的这个区间内,由于模式串的长度固定为,因此我们可以用终点的下标来表示,终点确定,也就确定。所以如果想出现在内,那么终点的下标要出现在中。
所以我们要求的是,在中,遍历每一个下标,以这个下标为终点且长度为的字符串有多少个是等于的,因此可以用前缀和的思想。
前缀和数组表示在的中,有多少个长度为且等于的字符串的数量。就表示在中,以这些下标为终点,长度为且等于的字符串的个数。
这种做法的时间复杂度是的。
AC代码如下:
1 #include <cstdio> 2 #include <iostream> 3 #include <string> 4 #include <algorithm> 5 using namespace std; 6 7 const int N = 1010; 8 9 string str, t; 10 int s[N]; 11 12 int main() { 13 int n, m, tot; 14 cin >> n >> m >> tot; 15 cin >> str >> t; 16 17 str = ' ' + str; // str从下标1k开始 18 for (int i = m; i <= n; i++) { // 因为t的长度为m,所以至少从下标m开始,m之前的下标不可能会有t 19 s[i] = s[i - 1]; 20 if (str.substr(i - m + 1, m) == t) s[i]++; // 判断以i为终点,长度为m的字符串是否为t 21 } 22 23 while (tot--) { 24 int l, r; 25 cin >> l >> r; 26 l += m - 1; 27 cout << (l > r ? 0 : s[r] - s[l - 1]) << endl; // 要保证l <= r 28 } 29 30 return 0; 31 }
参考资料
AcWing 4312. 出现次数(AcWing杯 - 周赛):https://www.acwing.com/video/3729/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/15999706.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
2021-03-13 图解带头节点的单链表的反转操作