二进制之和| 豆包MarsCode AI刷题

100 阅读7分钟

问题描述

小U和小R喜欢探索二进制数字的奥秘。他们想找到一个方法,将两个二进制字符串相加并以十进制的形式呈现。这个过程需要注意的是,他们的二进制串可能非常长,所以常规的方法可能无法处理大数。小U和小R希望你帮助他们设计一个算法,该算法能在保证时间复杂度不超过O(n^2)的前提下,返回两个二进制字符串的十进制求和结果。


测试样例

样例1:

输入:binary1 = "101" ,binary2 = "110"
输出:'11'

样例2:

输入:binary1 = "111111" ,binary2 = "10100"
输出:'83'

样例3:

输入:binary1 = "111010101001001011" ,binary2 = "100010101001"
输出:'242420'

样例4:

输入:binary1 = "111010101001011" ,binary2 = "10010101001"
输出:'31220'

样例5:

输入:binary1 = "11" ,binary2 = "1"
输出:'4'

解题思路

  1. 对齐二进制字符串

    • 找到两个二进制字符串中较长的那个长度。
    • 在较短的字符串前面补0,使得两个字符串长度相同。
  2. 逐位相加

    • 从右到左逐位相加,同时考虑进位。
    • 如果当前位的和大于等于2,则需要进位。
  3. 处理进位

    • 如果最高位有进位,需要将其加入结果中。
  4. 转换为十进制

    • 将最终的二进制结果转换为十进制字符串。

相关代码解释

  1. 头文件包含

    #include <iostream>
    #include <string>
    #include <algorithm>
    
    • iostream:用于输入输出操作。
    • string:用于处理字符串。
    • algorithm:用于使用std::reverse函数。
  2. 函数定义

    std::string solution(const std::string& binary1, const std::string& binary2) {
    
    • solution函数接受两个二进制字符串作为输入,并返回它们的十进制求和结果。
  3. 找到最长的字符串长度

    int max_length = std::max(binary1.length(), binary2.length());
    
    • 使用std::max函数找到两个字符串中较长的那个长度。
  4. 在左边补0对齐

    std::string padded_binary1 = std::string(max_length - binary1.length(), '0') + binary1;
    std::string padded_binary2 = std::string(max_length - binary2.length(), '0') + binary2;
    
    • 使用std::string的构造函数在较短的字符串前面补0,使得两个字符串长度相同。
  5. 逐位相加

    int carry = 0;
    std::string result = "";
    
    for (int i = max_length - 1; i >= 0; --i) {
        int b1 = padded_binary1[i] - '0';
        int b2 = padded_binary2[i] - '0';
        int total = b1 + b2 + carry;
        
        if (total >= 2) {
            result += std::to_string(total % 2);
            carry = total / 2;
        } else {
            result += std::to_string(total);
            carry = 0;
        }
    }
    
    • 从右到左逐位相加,同时考虑进位。
    • b1b2分别是当前位的二进制数字。
    • total是当前位的和加上进位。
    • 如果total大于等于2,则需要进位,否则不需要。
  6. 处理进位

    if (carry) {
        result += std::to_string(carry);
    }
    
    • 如果最高位有进位,需要将其加入结果中。
  7. 反转结果并转换为十进制字符串

    std::reverse(result.begin(), result.end());
    return std::to_string(std::stoi(result, nullptr, 2));
    
    • 使用std::reverse反转结果字符串。
    • 使用std::stoi将二进制字符串转换为整数,然后使用std::to_string将其转换为十进制字符串。
  8. 主函数

    int main() {
        std::cout << (solution("101", "110") == "11") << std::endl;
        std::cout << (solution("111111", "10100") == "83") << std::endl;
        std::cout << (solution("111010101001001011", "100010101001") == "242420") << std::endl;
        std::cout << (solution("111010101001011", "10010101001") == "31220") << std::endl;
        return 0;
    }
    
    • 测试solution函数,输出结果是否正确。

通过以上步骤,我们可以实现将两个二进制字符串相加,并将结果转换为十进制字符串的功能。

知识总结

  1. 字符串处理

    • 补0对齐:在C++中,可以使用std::string的构造函数在字符串前面补0。
    • 字符串反转:使用std::reverse函数可以反转字符串。
    • 字符串转换:使用std::stoi将二进制字符串转换为整数,使用std::to_string将整数转换为字符串。
  2. 二进制加法

    • 逐位相加:从右到左逐位相加,同时考虑进位。
    • 进位处理:如果当前位的和大于等于2,则需要进位。
  3. 时间复杂度

    • 对齐字符串O(n),其中 n 是较长的字符串长度。
    • 逐位相加O(n),其中 n 是较长的字符串长度。
    • 转换为十进制O(n),其中 n 是结果字符串的长度。
  4. 空间复杂度

    • 结果列表O(n),其中 n 是较长的字符串长度。
    • 进位变量O(1)

学习计划

  1. 基础知识

    • 字符串操作:深入学习C++中字符串的操作,包括拼接、反转、转换等。
    • 二进制运算:理解二进制加法的原理,掌握逐位相加和进位处理的方法。
  2. 进阶知识

    • 大数运算:学习如何处理大数运算,了解C++中处理大数的库(如boost::multiprecision)。
    • 时间复杂度分析:深入理解时间复杂度分析,掌握常见算法的时间复杂度。
  3. 实践练习

    • 编写代码:多练习编写类似的二进制加法代码,尝试处理不同长度的二进制字符串。
    • 调试技巧:学习调试技巧,掌握如何使用调试工具(如GDB)来调试代码。

工具运用

1. AI 刷题功能的优势

  • 即时反馈:AI 刷题工具可以即时提供代码的正确性反馈,帮助你快速发现和纠正错误。
  • 个性化指导:AI 可以根据你的代码表现提供个性化的建议和改进方案。
  • 自动化测试:AI 可以自动运行测试用例,帮助你验证代码的正确性。

2. 结合其他学习资源

  • 在线课程和教程

    • 学习资源:利用在线平台(如Coursera、edX、Udemy)上的C++课程,系统学习语言基础和高级特性。
    • 实践建议:在学习过程中,使用 AI 刷题工具进行练习,将理论知识应用到实际问题中。
  • 书籍和文档

    • 学习资源:阅读经典的C++书籍(如《C++ Primer》、《Effective C++》)和官方文档(如C++标准文档)。
    • 实践建议:在学习过程中,使用 AI 刷题工具进行练习,将书中的概念和技巧应用到实际问题中。
  • 开源项目

    • 学习资源:参与开源项目,阅读和贡献代码,学习实际项目中的最佳实践。
    • 实践建议:在参与开源项目时,使用 AI 刷题工具进行练习,提升代码质量和解决问题的能力。
  • 编程社区和论坛

    • 学习资源:加入编程社区(如Stack Overflow、GitHub Discussions),参与讨论,学习他人的经验和技巧。
    • 实践建议:在社区中提问和回答问题时,使用 AI 刷题工具进行练习,提升解决问题的能力。

3. 学习计划和时间管理

  • 制定学习计划

    • 目标设定:设定明确的学习目标,如每周完成一定数量的题目或掌握某个特定的C++特性。
    • 时间管理:合理安排学习时间,确保每天都有固定的时间用于学习和练习。
  • 定期复习和总结

    • 复习:定期回顾已完成的题目和学习内容,巩固记忆。
    • 总结:定期总结学习心得和经验,记录遇到的难点和解决方法。

4. 实践和项目

  • 小项目练习

    • 项目选择:选择一些小项目(如实现一个简单的计算器、文本编辑器)进行练习。
    • 实践建议:在项目中使用 AI 刷题工具进行练习,提升代码质量和解决问题的能力。
  • 参与竞赛和挑战

    • 竞赛:参加编程竞赛(如ACM、Google Code Jam),提升解决复杂问题的能力。
    • 挑战:参与编程挑战(如LeetCode、HackerRank),提升算法和数据结构的理解。