【华为od刷题(C++)】HJ30 字符串合并处理

我的代码:

#include //用于输入输出流
#include //用于字符串处理
#include //用于动态数组的处理
#include //包含排序等常见算法
#include //用于字符串流的处理,可以将数据从字符串流中提取
#include //提供字符处理函数,如 isdigit、isalpha 等
#include //提供位集处理,能够将数字转换为二进制表示
using namespace std;

char bitToHex(string s) {
//这个函数将一个 4 位二进制字符串(s)转换为一个十六进制字符

    int t = (s[0] * 1 - 48) * 8 + (s[1] * 1 - 48) * 4 + (s[2] * 1 - 48) * 2 + (s[3] * 1 - 48) * 1;
    //s[0] 是字符类型(比如 '0' 或 '1')
    //s[0] * 1 只是将字符转换为数字,不改变值

    //- 48 将字符 '0' 和 '1' 转换为对应的整数值
    //例如,字符 '0' 的 ASCII 值是 48,字符 '1' 的 ASCII 值是 49
    //因此 s[0] * 1 - 48 将 '0' 转换为 0,'1' 转换为 1

    /*这行代码将一个4位二进制字符串(s)通过计算各个字符的权重值,
    并将其转换为一个对应的十进制整数*/

    char ch = ' ';
    switch (t) {
    //switch 语句将数字转换为相应的十六进制字符
    //(例如 10 转换为 'A',11 转换为 'B' 等)

        case 10:
            ch = 'A';
            break;
        case 11:
            ch = 'B';
            break;
        case 12:
            ch = 'C';
            break;
        case 13:
            ch = 'D';
            break;
        case 14:
            ch = 'E';
            break;
        case 15:
            ch = 'F';
            break;
        default:
            ch = char(t + 48);
        /*如果 t 不是 10 到 15 之间的数字(例如 t 是 0 到 9 之间的数字),
        default 会执行,将 ch 赋值为 t + 48,这一操作将数字 t 转换为字符
        
        因为数字字符 '0' 的 ASCII 值是 48,
        所以 t + 48 会将数字 0 转换为字符 '0',1 转换为字符 '1',依此类推*/
    }
    return ch;
}
int main() {
    string s1, s2;//s1, s2 用来存储输入的两个字符串

    vector result;
    //result 是一个 vector,用于存储最终处理的所有结果字符串

    while (cin >> s1 >> s2) {//循环读取输入的两个字符串 s1 和 s2

        string s = s1 + s2;//合并两个输入的字符串

        vector odd;//用于存储奇数位置字符
        vector even;//用于存储偶数位置字符

        int size = s.size();//size 存储字符串 s 的长度

        //将字符串按奇偶位置分开
        for (int i = 0; i < size; ++i) {
            if (i % 2 == 0) {
                even.push_back(s[i]);
            //如果字符的索引 i 是偶数(i % 2 == 0),则将字符存入 even 向量

            } else {
                odd.push_back(s[i]);
            //如果字符的索引 i 是奇数,则将字符存入 odd 向量
            }
        }

        //对奇数和偶数位置的字符分别排序
        sort(even.begin(), even.end());
        sort(odd.begin(), odd.end());

        //存储新的字符串
        string ns;//ns 用来存储重新构建后的字符串

        int eveni = 0;
        int oddi = 0;
        //eveni 和 oddi 分别是 even 和 odd 向量的索引
        //指示当前正在使用的字符位置

        //构建新的字符串
        for (int i = 0; i < size; ++i) {
            if (i % 2 == 0) {
                ns += even[eveni];
                eveni++;
            } else {
                ns += odd[oddi];
                oddi++;
            }
        }/*遍历每个字符的位置 i,
        如果 i 是偶数,选择 even 中的字符,
        如果是奇数,选择 odd 中的字符
        
        使用 eveni 和 oddi 分别控制 even 和 odd 向量的索引*/

        string results;//results 用来存储最终的处理结果

        string num = "0123456789ABCDEF";//用于转化十六进制的字符集

        // 对构建后的字符串进行处理
        for (int i = 0; i < size; ++i) {
            if (isdigit(ns[i]) || (ns[i] >= 'A' && ns[i] <= 'F') || (ns[i] >= 'a' && ns[i] <= 'f')) {
        //检查每个字符是否为有效的十六进制字符(0-9, A-F 或 a-f)
        //isdigit(ns[i]) 是一个用于检查字符 ns[i] 是否是数字字符(0-9)的函数

                stringstream ss;
                /*stringstream 是 C++ 标准库中的一种输入输出流,
                它允许你将数据读写到一个字符串中,而不是常规的文件或控制台
                
                stringstream 的作用:

                将数据写入字符串:
                可以像使用输出流(例如 cout)一样,
                使用 stringstream 将数据写入一个字符串

                从字符串读取数据:
                也可以像使用输入流(例如 cin)一样,
                从一个字符串中读取数据*/

                //找到对应字符在十六进制中的位置,转化为二进制
                ss << bitset<4>(num.find(toupper(ns[i])));
                /*将 ns[i] 这个字符(转换为大写字母后)
                在 num 字符串中的位置(索引值)
                转换成一个 4 位的二进制表示,
                并将其存入一个 stringstream(ss)中
                
                toupper() 是 C++ 的标准库函数,
                用于将字符 ns[i] 转换为大写字母
                如果 ns[i] 已经是大写字母,则它会保持不变
                
                num 是一个字符串,
                find() 方法用于查找一个字符(这里是大写的 ns[i])
                在 num 中首次出现的位置(索引值)

                find() 会返回该字符在 num 中的索引
                如果未找到字符,则返回 string::npos,表示“未找到”
                
                bitset<4> 是 C++ 中的一个模板类,
                用于将整数值表示为二进制格式
                它接受一个整数并返回一个包含 4 个二进制位的 bitset 对象
                
                num.find(toupper(ns[i])) 返回的是一个整数(字符的位置索引),
                该值被转换为一个 4 位的二进制字符串
                
                如果位置索引大于 15(即 4 位无法容纳),
                它将只显示最低的 4 位
                
                如果 num.find(toupper(ns[i])) 
                返回 string::npos(即未找到字符),
                则可能会导致错误或者不预期的结果,
                因为 string::npos 对应的是一个非常大的数*/

                string s = ss.str();
                /*从 stringstream 中获取所有已写入的内容,
                并将其保存到一个 string 类型的变量 s 中
                
                ss.str() 是 stringstream 提供的一个成员函数,
                它返回一个包含流中所有内容的 string 对象*/

                reverse(s.begin(), s.end());//将二进制结果反转
                /*将对字符串 s 的字符进行反转操作,
                即将第一个字符和最后一个字符交换,
                第二个字符和倒数第二个字符交换,以此类推
                
                s.begin() 返回字符串 s 的起始迭代器
                s.end() 返回字符串 s 的末尾迭代器
                (指向最后一个字符之后的位置)*/

                results += bitToHex(s);
                //转换成十六进制字符并追加到结果字符串中
            } else {
                results += ns[i];//不是十六进制字符,直接添加
            }
        }

        result.push_back(results);//将处理结果存入最终结果数组
        s1.clear();//清空字符串 s1
        s2.clear();//清空字符串 s2
    }

    //输出所有处理后的结果
    for (auto i : result) {
        cout << i << endl;
    }
    return 0;
}

这段代码的功能是对输入的字符串进行处理,具体步骤如下:

1. 函数 bitToHex 解释:

bitToHex 函数将一个 4 位的二进制字符串(如 "0101")转换成一个十六进制字符(如 '5');这部分的核心步骤是:

  • 将每个字符('0' 或 '1')转换为相应的数字 0 或 1
  • 计算对应的十进制值(将二进制转换为十进制)
  • 使用 switch 语句将十进制数(0 到 15)转换为十六进制字符,如果是 10 到 15 就转为 'A' 到 'F',否则转为数字字符

2. main 函数解释:

main 函数的作用是接收一对字符串,并对这些字符串做如下处理:

  • 字符串合并: 首先合并输入的两个字符串 s1s2,然后将它们的字符按奇数和偶数索引位置分别存入两个不同的数组中

  • 奇偶分离: 遍历合并后的字符串,分别将字符放入 even(偶数位置)和 odd(奇数位置)数组

  • 排序: 分别对 evenodd 数组进行排序

  • 重建字符串: 根据排序后的 evenodd 数组重新构建一个新的字符串 ns

  • 字符检查和转换:

    • 对新字符串中的每个字符进行检查,如果是有效的十六进制字符(0-9,A-F,a-f),则将其转换为二进制,并再转换为十六进制字符
    • 对于每个字符,利用 stringstream 和 bitset 转换为二进制,再使用 bitToHex 将其转换为十六进制
    • 非十六进制字符则直接添加到结果字符串 results 中
  • 结果输出: 最终的处理结果保存在 result 向量中,最后输出所有处理后的结果

3. 重点操作:

  • 二进制转十六进制: 使用 bitset 类和 stringstream 来将字符转换为二进制并进行反转,然后再将其转换为十六进制字符
  • 奇偶排序: 通过分离字符串中的奇偶字符,分别排序并再组合,可能用于某种加密或混排操作
  • 字符串处理: 包括字符的检查、转换和拼接,这是一种典型的字符操作技术

4. 流程图的简化:

  1. 输入: 两个字符串 s1 和 s2
  2. 合并字符串: 将 s1 和 s2 合并
  3. 分离奇偶位置: 将合并后的字符串按奇偶索引分成两个数组
  4. 排序: 对 even 和 odd 数组分别进行排序
  5. 重建新字符串: 根据排序后的字符重新构建字符串
  6. 字符检查: 对每个字符检查并进行十六进制转二进制再转回十六进制
  7. 结果输出: 输出最终的处理结果

5. 改进和优化建议:

  • 错误处理: 如果输入的字符串无法转换为有效的十六进制字符,可以加入错误处理机制,避免程序崩溃
  • 性能优化: 对于大的输入,字符串的拼接和多次排序可能影响性能;可以考虑优化字符串合并和排序操作

总体来说,这段代码展示了如何处理字符串、排序、字符转换和输出

你可能感兴趣的:(华为od,c++,链表)