题目背景
disangan233 喜欢字符串,于是 disangan333 想让你找一些 disangan233 喜欢的串。
题目描述
在传智的开发课堂上,希望您开发一款文档处理软件。
给定 TT 组询问,每次给定 22 个长度为 n,mn,m 的只含英文字母的字符串 a,ba,b,求 aa 在 bb 中的出现次数,相同字符不区分大小写。注意 aa 是 bb 中连续子序列。
对于所有数据,T\leq 100T≤100,\sum n\leq \sum m\leq 10^3∑n≤∑m≤103。字符串仅由大小或者小写的英文字母组成。
输入格式
输入共 3T+13T+1 行。
第 11 行输入 11 个正整数 TT。
接下来共 TT 组输入,每组输入共 33 行。
第 11 行输入 22 个正整数 n,mn,m。
第 22 行输入一个长度为 nn 的字符串 aa。
第 33 行输入一个长度为 mm 的字符串 bb。
输出格式
输出共 TT 行,第 ii 行输出 11 个整数,表示询问 ii 的答案。
输入输出样例
输入 #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
KMP 算法详解👉 P8195 [传智杯 #4 决赛] 小智的疑惑 ----- 字符串匹配、KMP算法优化next数组 - slowlydance2me - 博客园 (cnblogs.com)
#include <iostream>
#include<iomanip>
#include <math.h>
#include <vector>
#include <unordered_set>
using namespace std;
vector<int> get_next(string a) {
int n = a.size();
vector<int> next;
next.push_back(0);
int left = 0, right = 1;
while (right < n) {
if (a[left] == a[right] || a[left] == a[right] - 32 || a[left] == a[right] + 32) {
left++;
right++;
next.push_back(left);
}
else if (left) {
left = next[left - 1];
}
else {
next.push_back(0);
right++;
}
}
return next;
}
int main() {
vector<int> resvec;
int T ,n, m;
cin >> T;
while (T--) {
int res = 0;
string a, b;
cin >> n >> m;
cin >> a;
cin >> b;
vector<int> next = get_next(a);
int i = 0, j = 0;
while (i < m) {
if (b[i] == a[j] || b[i] == a[j] - 32 || b[i] == a[j] + 32) {
j++;
i++;
}
else if(j) {
j = next[j - 1];
}
else {
i++;
}
if (j == n) res++, j = next[j - 1];
}
cout << res << endl;
//resvec.push_back(res);
}
//cout << resvec[0];
//for (int i = 1; i < resvec.size(); ++i) cout << endl << resvec[i];
return 0;
}
字母大小写转换三种方法:
-
+/- 32
-
字符数组 strupr/strlwr
-
对字符使用toupper、tolower / 利用transform和tolower及toupper进行结合