如何在给定起点和终点的字符串中查找子字符串的出现次数?
How to find number of occurrences of a substring in a string given starting point and ending point?
给定一个字符串和一个子字符串,以及起点和终点的索引,我希望能够在边界中找到该子字符串的出现次数。例如,给定字符串"ACACTACG",我想找到子字符串"AC"从 3 到 7 的出现次数(如果第一个索引为 1)。上面的示例生成输出 2。从 3 到 7,我们有"ACTAC",其中子字符串"AC"出现了 2 次。我似乎无法用C++编码;
这是 AtCoder 初学者竞赛 122 的问题 C:https://atcoder.jp/contests/abc122/tasks/abc122_c
我实际上设法将其编码出来,但超过了时间限制。我需要一种更简单的方法。
这是我提交的TLE结果:
#include <iostream>
using namespace std;
int main()
{
int N, Q;
string s;
cin >> N >> Q >> s;
for(int i = 0; i < Q; i++)
{
int l, r;
cin >> l >> r;
if(l >= r)
{
cout << 0 << endl;
break;
}
int count = 0;
for(int j = l - 1; j < r; j++)
{
if(s[j] == 'A' && s[j + 1] == 'C' && j != r - 1)
{
count++;
j++;
}
}
cout << count << endl;
}
return 0;
}
在做了一些数学运算后,我设法发现我得到TLE的原因是因为我的代码大约有10 ^10条指令,而2秒的时间限制只能执行大约2 * 10 ^8条指令。
字符串 N 对于所有查询都是相同的,您只是在查找模式AC
。这意味着您可以预先计算查找表的答案,并避免为每个查询迭代 N。
查找表将具有自字符串开头以来AC
出现的次数。对于ACACTACG来说,这将是
A={0,1,1,2,2,2,3,3}
这很有帮助,因为"x 和 y 之间的 AC 出现次数"与"y 之前的出现次数相同,除了 x 之前的出现次数"。每当您必须回答有关范围的问题时,此类表通常很有用
例如,要回答查询 3,7,您需要计算 A[7]-A[3] = 3-1 = 2。
正如Joni所说,您可以创建像arr 这样的查找Arr。由于要匹配的模式的长度为 2,因此基本思想是:
- 首先创建一个长度为n+1的数组,所有值都填充0。
- 其次,当您匹配字符串中的
AC
时,您尝试匹配字符串s中的模式AC
因此,当您匹配字符串中的时,请在arr中的C
索引处标记1。 - 这样,您将在回答任何查询之前仅迭代数组一次
- 对于每个查询,您可以在O(1)时间内解决此问题,因为找到的总模式将
arr[r] - arr[l-1]
- 注意,请确保查找部分重叠,如以下代码中所述
希望这有帮助:
// This program is created by Ishpreet Singh
#include <iostream>
#include <string>
using namespace std;
int main()
{
int n, q, l, r;
string s;
cin >> n >> q;
cin >> s;
// The lookUp Arr
int arr[n + 1];
arr[0] = arr[1] = 0;
for (int i = 1; i < n; i++)
{
if (s.at(i - 1) == 'A' && s.at(i) == 'C'){
arr[i + 1] = arr[i] + 1;
}
else{
arr[i + 1] = arr[i];
}
}
while (q--)
{
cin >> l >> r;
int ans = arr[r] - arr[l - 1];
// To Remove partial overlaps of AC, like s[l-1] = 'A' and s[l] = 'C'
if (l > 1 && arr[l] == arr[l - 1] + 1){
ans--;
}
cout << ans << endl;
}
return 0;
}
通过这种方式,您可以在O(1)
时间内回答查询,因此代码的整体复杂性将O(Q)
这将在 1 秒内通过所有测试用例。
相关文章:
- 使用正则表达式regex_search在字符串中查找字符串
- 按类型与字符串查找对象
- 使用C RTTI(内置)通过字符串查找功能指针
- 关于获取行和字符串查找函数的问题
- 字符串查找方法找不到第一字母
- C++ 字符串.查找()
- 遇到字符串::查找的问题
- 将一个数组作为子字符串查找到另一个数组中
- 字符串查找第一个非的 C++ 问题
- 如何将通配符与字符串::查找一起使用
- 字符串::查找问题 (C++)
- 性能标准::strstr vs. 标准::字符串::查找
- C++字符串::查找崩溃应用程序
- 使用字符串查找单词的正确方法是什么
- 如何在<string>没有 std::string 中介的情况下制作一个支持通过 C 字符串查找的集合?
- 使用C++根据行中的第一个字符串查找行(仅一个)
- Borland字符串::查找bug
- std::map如何通过字符串查找元素
- 字符串查找函数返回奇数
- 如何使用子字符串查找数字行的正确部分