P8835 [传智杯 #3 决赛] 子串

121 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第17天,点击查看活动详情

[传智杯 #3 决赛] 子串

题目背景

disangan233 喜欢字符串,于是 disangan333 想让你找一些 disangan233 喜欢的串。

题目描述

在传智的开发课堂上,希望您开发一款文档处理软件。

给定 TT 组询问,每次给定 22 个长度为 n,mn,m 的只含英文字母的字符串 a,ba,b,求 aabb 中的出现次数,相同字符不区分大小写。注意 aabb 中连续子序列。

对于所有数据,T100T\leq 100nm103\sum n\leq \sum m\leq 10^3。字符串仅由大小或者小写的英文字母组成。

输入格式

输入共 3T+13T+1 行。

11 行输入 11 个正整数 TT

接下来共 TT 组输入,每组输入共 33 行。

11 行输入 22 个正整数 n,mn,m

22 行输入一个长度为 nn 的字符串 aa

33 行输入一个长度为 mm 的字符串 bb

输出格式

输出共 TT 行,第 ii 行输出 11 个整数,表示询问 ii 的答案。

样例 #1

样例输入 #1

5
3 10
abc
abcabcabca
2 10
aa
AAaAaaAaAa
5 5
AbCdE
eDcBa
5 5
abcde
ABCDE
3 10
aba
ABaBaAbaBA

样例输出 #1

3
9
0
1
4

提示

对于第一组输入,出现了 33 次,分别是 [abc]abcabcaabc[abc]abcaabcabc[abc]a

对于第二组输入,出现了 99 次,分别是 [Aa]AaaAaAaA[aA]aaAaAaAa[Aa]aAaAaAaA[aa]AaAaAaAa[aA]aAaAaAaa[Aa]AaAaAaaA[aA]aAaAaaA[aA]aAaAaaAa[Aa]

思路分析

  • 对于这题,注意一个特殊的测试用例——一连串的a,这告诉我们删除字符串子串的时候不能全删了,而是要删第一个
  • 很无语的是,洛谷好像用不了transform来直接对字符串进行修改,只好自己写一个字符串变小写的了
  • 关键思路:我们使用string的find函数,找到了的话就加一,然后删除从开头到pos的全部子串(因为如果开头到pos存在子串的话早就被之前的操作删掉了,不会再存在,所以我们直接删除利于查找)

步骤

  • 1.编写字符串变小写的函数,将字符串a和b都变成小写字符串
  • 2.根据思路编写功能函数,返回a在b内的子串个数
  • 3.输出

代码呈现

#include<iostream>
#include<algorithm>
#include<string>
using namespace std;

//功能操作函数
int func(string a, string b) {
	int count = 0;
	int pos = b.find(a);
	while (pos != -1) {
		count++;
		b.replace(0, pos + 1, "");
		pos = b.find(a);
	}
	return count;
}

string stringFunc(string s) {
	for (int i = 0; i < s.size(); i++)
		s[i] = tolower(s[i]);
	return s;
}

int main()
{
	int t;
	cin >> t;
	int n, m;
	while (t--) {
		cin >> n >> m;
		string a, b;
		cin >> a >> b;
		//因为大小写不记,所以统一使用小写
		a = stringFunc(a);
		b = stringFunc(b);
		cout << func(a, b) << endl;
	}
	return 0;
}

PS:真无语洛谷不能用transform啊~