我的代码:
#include <iostream>//用于输入输出操作
#include <string>//用于处理字符串
#include <set>//用于存储不重复的元素,自动排序
#include <vector>//动态数组,允许存储不同类型的元素
#include <algorithm>//提供各种算法函数,如排序、查找等
#include <cstring>//提供对C风格字符串的操作(但在这段代码中并未用到)
using namespace std;
int main() {//程序的入口点
int num_I, num_R;
//num_I:用于存储第一组输入数据的大小
//num_R:用于存储第二组输入数据的大小
while (cin >> num_I) {//读取一个整数,表示第一组数据的大小
//如果成功读取,进入循环
//读取第一组数据 (para_I)
vector<string> para_I;
//定义了一个 vector<string> 来存储第一组数据 para_I(字符串集合)
set<int> para_R; // 自带去重和排序
string s;
while (num_I--) {
cin >> s;
para_I.push_back(s);
}//循环 num_I 次,读取每个字符串并存储到 para_I 中
//读取第二组数据 (para_R)
cin >> num_R;//读取第二组数据的大小
int a;
while (num_R--) {//循环 num_R 次
cin >> a;
para_R.insert(a);//读取每个整数并插入 para_R 中
/*如果 para_R 是一个集合或映射类型
(如 set, unordered_set, map, unordered_map),
insert(a) 会尝试将元素 a 插入到容器中,并确保没有重复元素
如果 para_R 是一个普通容器(如 vector),
请使用 push_back(a) 来插入元素*/
}
vector<vector<string>> ans(para_R.size()); // 每行存放一组结果
//定义一个二维 vector,用于存储每个R元素对应的结果
//每个 para_R 元素将对应一个 vector<string> 用来存储与之匹配的I元素
/*para_R.size() 返回容器中元素的数量,
适用于大多数 STL 容器(如 vector, set, map 等)
它的返回值类型是 size_t,通常是无符号整数,用来表示容器中元素的个数*/
int dex = 0;//dex 用于追踪当前处理的 para_R 元素的位置
//dex 是 ans 中的索引,表示当前操作的二维数组的第 dex 行
for (auto i = para_R.begin(); i != para_R.end(); i++) {
//遍历 para_R 中的每个元素 *i
/*auto 是 C++ 的一个关键字,表示让编译器自动推断变量 i 的类型
这里 i 会被推断为容器 para_R 的迭代器类型
para_R.begin() 返回指向容器第一个元素的 迭代器
*i 用于解引用迭代器,得到迭代器指向的元素的值*/
int count = 0;
for (int j = 0; j < para_I.size(); j++) {
int pos = para_I[j].find(to_string(*i)); // 是否包含R元素
//在 para_I[j] 字符串中查找由 *i 指向的整数转换为字符串后的值
/*对于每个R元素,遍历 para_I 中的每个字符串,
查找是否包含R元素(即R元素作为子串出现在I元素中)
这通过 find() 方法实现,
find() 如果找到子串,会返回该子串的起始位置,否则返回 npos*/
if (pos != para_I[j].npos) {
ans[dex].push_back(to_string(j));//将整数 j 转换成对应的字符串形式
ans[dex].push_back(para_I[j]);
count++;
}//如果找到了,记录该索引 j 和 para_I[j],并增加计数 count
}
if (count != 0) {
ans[dex].insert(ans[dex].begin(), to_string(count));
//将 count 转换为字符串后,插入到 ans[dex] 的开头
ans[dex].insert(ans[dex].begin(), to_string(*i)); // 对应R中的元素加前面
//将 *i 指向的整数值(转换为字符串)插入到 ans[dex] 的开头,
//位于刚才插入的 count 字符串之前
}
dex++;
}//最后,如果找到了至少一个匹配,将该R元素和匹配的数量放到 ans[dex] 中
int sum = 0;//sum 用于存储所有结果的总元素个数
for (auto i : ans)//遍历 ans 中的每个元素,累加它们的大小到 sum
sum += i.size();
cout << to_string(sum) << ' ';//输出 sum(总元素个数)
for (auto i : ans)
for (auto j : i)
cout << j << ' ';//输出 ans 中所有的元素(即所有的匹配结果)
cout << endl;
}
}
这段代码的核心思路是处理两组输入数据:一组是字符串数据,另一组是整数数据;代码的任务是查找每个整数数据(来自第二组输入)是否作为子串出现在第一组字符串数据中,并将匹配结果按照一定规则输出
1. 输入解析:
首先,代码通过 cin
来读取两组输入数据:
- 第一组:由若干个字符串构成
- 第二组:由若干个整数构成
这两组数据的读取方式是:
- num_I 表示第一组数据(字符串)的数量
- num_R 表示第二组数据(整数)的数量
通过这些数据,我们可以理解输入数据的结构
2. 数据结构选择:
vector<string>
para_I:这是一个动态数组,用来存储第一组输入的字符串数据;vector
可以根据需要自动扩展大小,允许动态存储不确定数量的元素set<int>
para_R:这是一个集合,用来存储第二组输入的整数数据;set
的特点是自动去重,并且会对元素进行排序(升序)
3. 第一组数据处理:
在读取完 num_I
(第一组数据的大小)后,进入一个循环,将每个字符串存储到 para_I
中
vector<string> para_I;
while (num_I--) {
cin >> s;
para_I.push_back(s);
}
- 每次循环读取一个字符串,将其推入
para_I
中
4. 第二组数据处理:
在读取完 num_R
(第二组数据的大小)后,进入另一个循环,读取每个整数并将其插入到 para_R
中;由于使用了 set<int>
,插入的整数会自动去重,并且按升序排列
set<int> para_R;
while (num_R--) {
cin >> a;
para_R.insert(a);
}
- 每次循环读取一个整数
a
,将其插入到para_R
中
5. 数据匹配:
这是程序的关键部分,主要思路是:对每个 para_R
中的整数,查找它是否作为子串出现在 para_I
中的某个字符串里
vector<vector<string>> ans(para_R.size());
- 每个
para_R
中的元素对应一个vector<string>
,来存储该元素匹配的结果
-
遍历
para_R
中的每个整数: 我们遍历para_R
中的每个元素,对于每个元素(假设为r
),我们需要判断它是否在para_I
中的某个字符串中出现作为子串;通过find()
函数进行查找:for (auto i = para_R.begin(); i != para_R.end(); i++) { int count = 0; for (int j = 0; j < para_I.size(); j++) { int pos = para_I[j].find(to_string(*i)); if (pos != para_I[j].npos) { ans[dex].push_back(to_string(j)); ans[dex].push_back(para_I[j]); count++; } } if (count != 0) { ans[dex].insert(ans[dex].begin(), to_string(count)); //count 记录了找到匹配项的次数 ans[dex].insert(ans[dex].begin(), to_string(*i)); //i 是当前匹配的元素的索引 } dex++; } /*每次循环中,ans[dex] 会记录: 当前匹配元素(*i) 匹配次数(count) 对应的匹配元素索引(j) 具体的匹配元素内容(para_I[j])*/
- 外层循环:遍历
para_R
中的每个整数*i
- 内层循环:遍历
para_I
中的每个字符串para_I[j]
,使用find()
查找当前整数是否作为子串出现在该字符串中para_I[j].find(to_string(*i))
:将*i
转换为字符串后,在para_I[j]
中查找该字符串;如果找到子串,find()
会返回子串的起始位置;如果找不到,则返回npos
- 如果找到匹配:将当前字符串的索引(
to_string(j)
)和该字符串(para_I[j]
)添加到对应的ans[dex]
中 - 如果找到了至少一个匹配,则在
ans[dex]
的最前面插入匹配的数量和当前para_R
元素
- 外层循环:遍历
-
完整插入过程
假设:
para_R = {1}
para_I = {"apple", "1banana", "grape", "orange"}
-
对于
查找i = 1
:"1"
是否出现在para_I
中:"orange"
不包含1
"grape"
不包含1
"1banana"
包含1
,找到,索引是1
,字符串是"1banana"
"apple"
不包含1
-
插入
count
和i
:插入count
("1"
)和数字i
("1"
),结果是{"1", "1"};
-
插入匹配项:插入匹配项的索引(
"1"
)和字符串("1banana"
),最终结果是:
ans[dex] = {"1", "1", "1", "1banana"};
这个结果表示数字 1
在 para_I
中找到了一个匹配项,且该项的索引是 1
,对应的字符串是 "1banana"
6. 结果输出:
最后,程序需要输出所有的匹配结果:
-
计算总的匹配元素个数: 遍历
ans
,累加每个子集的元素个数,得到总的匹配元素个数int sum = 0; for (auto i : ans) sum += i.size();
-
输出总的匹配元素个数,以及所有的匹配结果:
cout << to_string(sum) << ' '; for (auto i : ans) for (auto j : i) cout << j << ' '; cout << endl;
7. 总结:
- 输入分为两部分,第一部分是字符串数据,第二部分是整数数据
- 程序通过查找每个整数是否作为子串出现在字符串数据中来进行匹配
- 最后输出总的匹配结果,包括匹配的总元素数和每个匹配的详细内容
这段代码的核心思路是:通过 set
去重、find
查找子串,然后用二维 vector
存储结果,最后输出所有匹配的详细信息