【华为od刷题(C++)】HJ25 数据分类处理

我的代码:

#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>,来存储该元素匹配的结果
  1. 遍历 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 元素
  2. 完整插入过程

    假设:

  • para_R = {1}
  • para_I = {"apple", "1banana", "grape", "orange"}
  1. 对于 i = 1

    查找 "1" 是否出现在 para_I 中:
    • "orange" 不包含 1
    • "grape" 不包含 1
    • "1banana" 包含 1,找到,索引是 1,字符串是 "1banana"
    • "apple" 不包含 1
  2. 插入 counti:插入 count"1")和数字 i"1"),结果是 {"1", "1"};

  3. 插入匹配项:插入匹配项的索引("1")和字符串("1banana"),最终结果是:

ans[dex] = {"1", "1", "1", "1banana"};

这个结果表示数字 1para_I 中找到了一个匹配项,且该项的索引是 1,对应的字符串是 "1banana"

6. 结果输出:

最后,程序需要输出所有的匹配结果:

  1. 计算总的匹配元素个数: 遍历 ans,累加每个子集的元素个数,得到总的匹配元素个数

    int sum = 0;
    for (auto i : ans)
        sum += i.size();
    
  2. 输出总的匹配元素个数,以及所有的匹配结果:

    cout << to_string(sum) << ' ';
    for (auto i : ans)
        for (auto j : i)
            cout << j << ' ';
    cout << endl;
    

7. 总结:

  • 输入分为两部分,第一部分是字符串数据,第二部分是整数数据
  • 程序通过查找每个整数是否作为子串出现在字符串数据中来进行匹配
  • 最后输出总的匹配结果,包括匹配的总元素数和每个匹配的详细内容

这段代码的核心思路是:通过 set 去重、find 查找子串,然后用二维 vector 存储结果,最后输出所有匹配的详细信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值