4 条题解
-
2
感谢楼上题解,不过我认为可以不用转为int再放到数组里面,可以直接减去字符a后变为0-25然后再计算频率会更清楚一点,然后就是这个编辑器是markdown格式的,可以加代码块,不加代码块直接发出来会看的很头疼。总结:感谢楼上题解[花]
#include<bits/stdc++.h> using namespace std; int main() { int T; cin>>T; int Q; string s; for(int i=1; i<=T; i++) { cin>>s; // s是要匹配的字符串 cin>>Q; string zi; int len2 = s.size(); for(int j=1; j<=Q; j++) { cin>>zi; int len = zi.size(); int std[27]={0}; for(int k=0; k<len; k++) { std[zi[k] - 'a']++; } int ans=0; for(int k=0; k<len2 - len + 1; k++) { int jd[27]={0}; string judge=s.substr(k,len); for(int h=0; h<len; h++) { jd[judge[h] - 'a']++; } int flag = 1; for (int h = 0; h <= 26; h ++) { if (jd[h] != std[h]) { flag = 0; } } if (flag == 1) ans++; } cout<<ans<<endl; } } return 0; }
-
1
解题思路
1. 先对字符串进行预处理,获取每中长度的串
2. 由于abc,cba..这种属于同一种串,那么分开处理将会十分浪费时间,使用sort进行排序,可将同一类型的串变成同一个串。随后进行计数即可
3. 子串进行匹配前,也使用sort进行排序,便可以从map中查询到对应串的出现次数
完整代码如下:
#include <iostream> #include <map> #include <vector> #include <cstring> #include <algorithm> using namespace std; int main() { int T; cin >> T; for (int i = 0; i < T; i++) { string main_sec; cin >> main_sec; int n = main_sec.size(); int Q; cin >> Q; // 预处理:预先计算所有可能长度的字符频率 // 使用一个映射,键为长度,值为另一个映射(键为排序后的子串,值为出现次数) map<int, map<string, int>> precomputed; // 只处理长度1到10的子串(根据题目提示,子串长度<=10) for (int len = 1; len <= 10; len++) { for (int start = 0; start <= n - len; start++) { string substr = main_sec.substr(start, len); // 对子串排序,作为频率的标识 sort(substr.begin(), substr.end()); precomputed[len][substr]++; } } for (int j = 0; j < Q; j++) { string str; cin >> str; int len = str.size(); // 如果长度超过10或主串长度,直接返回0 if (len > 10 || len > n) { cout << 0 << endl; continue; } // 对查询子串排序,作为频率标识 sort(str.begin(), str.end()); // 直接从预处理结果中获取计数 if (precomputed.find(len) != precomputed.end() && precomputed[len].find(str) != precomputed[len].end()) { cout << precomputed[len][str] << endl; } else { cout << 0 << endl; } } } return 0; }
-
0
我之前没有学过字符串的相关知识,我是一边做题一边看书学出来。所以我觉得我的题解应该可以给像我一样的新手看,给予参考或者启发。 我的思路是,被匹配的字符串的每个字符都去匹配要匹配的字符串的字符,如果匹配到了,就标记被占用。核心思路是这个,然后配上辅助减少计算时间的方法就行了。应该会有更快的算法,但我想了很久想不出来。 下面的代码要用到的没教过的函数(目前)是strlen() (这个函数是我从课本扒出来的,需要<string.h>头文件),这个函数是求字符串长度的。然后其它的都是些课上讲的东西组合起来和我发现的一些小点。
#include <stdio.h> #include <string.h> int get_times(char main_str[], char sub_str[]) { int main_length = strlen(main_str); int sub_length = strlen(sub_str); int times = 0; // 遍历主串 int start = 0; int end = 0; for (int i = 0; i < main_length; i ++) { int match_array[15] = {0}; end = i; if ((end - start) == sub_length) { start += 1; } int match_times = 0; for (int j = start; j <= end; j ++) { for (int k = 0; k < sub_length; k ++) { if (main_str[j] == sub_str[k] && match_array[k] == 0) { match_array[k] = 1; match_times += 1; break; } } } if (match_times == sub_length) { times += 1; } } return times; } int main(void) { int t; int qs = 0; scanf("%d", &t); int times_array[20005] = {0}; int counter = -1; for (int i = 0; i < t; i ++) { char main_str[1005] = {0}; scanf("%s", main_str); int q; scanf("%d", &q); qs += q; for (int j = 0; j < q; j ++) { counter += 1; char sub_str[15] = {0}; scanf("%s", sub_str); times_array[counter] = get_times(main_str, sub_str); } } for (int i = 0; i < qs; i ++) { printf("%d\n", times_array[i]); } return 0; }
-
0
#include<bits/stdc++.h> using namespace std;
int main() { int T;
cin>>T; int Q; string s; for(int i=1; i<=T; i++) { cin>>s; cin>>Q; string zi; for(int j=1; j<=Q; j++) { cin>>zi; int std[1024]={0}; //子串的标准 for(int k=0; k<zi.size(); k++) { std[(int)zi[k]]++; } int ans=0; //一个Q对应一个ans for(int k=0; k<s.size()-zi.size()+1; k++) { int jd[1024]={0}; string judge=s.substr(k,zi.size());
// cout<<"查找的子串是:"<<judge<<endl; // cout<<"子串的长度是:"<<zi.size()<<endl;
for(int h=0; h<zi.size(); h++) { jd[(int)judge[h]]++; } int flag=1; for(int h=0; h<zi.size(); h++) {
// cout<<zi[h]<<':'<<"std:"<<std[(int)zi[h]]<<" VS "<<"jd:"<<jd[(int)zi[h]]<<endl;
if(std[(int)zi[h]]!=jd[(int)zi[h]]) flag=0;
// cout<<"flag:"<<flag<<endl; }
if(flag==1) ans++; } cout<<ans<<endl; } } return 0;
}
感觉我写的太丑陋了 抛砖引玉一下吧
- 1
信息
- ID
- 196
- 时间
- 4000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- 递交数
- 827
- 已通过
- 91
- 上传者