青训营X豆包MarsCode 二进制之和 | 豆包MarsCode AI 刷题

51 阅读4分钟

学习笔记:从二进制字符串求和到十进制转换

题目解析

今天的题目是:如何将两个二进制字符串相加并以十进制形式返回结果。刚开始思考这个题目时,觉得它只是基础的加法问题,但细想后发现,直接把二进制转换成十进制后相加,再转回二进制的常规方法对大数无效,这就要求我们自己手动实现整个加法过程。题目还要求时间复杂度不能超过 𝑂(𝑛^2),所以必须注重效率。

解题思路与代码编写过程

1. 题目分析

我的第一步是先分析题目要求: 输入是两个二进制字符串,可能长度不等。输出是它们相加后的十进制结果。 由于二进制字符串可能很长,直接用Python的 int 转换并计算可能会超出限制,所以需要手动实现二进制加法。

2. 解决二进制加法

二进制加法和我们熟悉的十进制加法很相似,不同之处在于进位规则: 0+0=0,无进位。 1+0=1,无进位。 1+1=10,需要进位。 1+1+1=11,需要进位。 所以我们需要逐位从右往左处理,记录进位并计算当前位的值。对于长度不等的字符串,可以把短的字符串用零补齐。

3. 设计代码

我的代码设计分为以下几步: 反向遍历字符串: 从最低位开始处理,这样方便计算和进位。 计算当前位: 将两数的当前位相加,再加上前一位的进位,得出这一位的结果。 记录结果: 用一个列表存储每一位的计算结果,这样更方便最后转为十进制。 处理进位: 如果最高位仍有进位,就在结果列表中再加一个1。 二进制转十进制: 遍历结果列表,按权重累加得到十进制值。

代码实现

以下是我的完整代码和注释:

    s = []  # 存储二进制加法的结果(反向存储)
    t = 0   # 进位值

    # 从右往左遍历
    i, j = len(binary1) - 1, len(binary2) - 1
    while i >= 0 or j >= 0:
        a = int(binary1[i]) if i >= 0 else 0  # 当前位,若越界则视为0
        b = int(binary2[j]) if j >= 0 else 0  # 当前位,若越界则视为0

        total = a + b + t  # 当前位相加再加进位
        if total == 3:  # 1 + 1 + 1
            s.append(1)
            t = 1
        elif total == 2:  # 1 + 1 或 0 + 0 + 1
            s.append(0)
            t = 1
        elif total == 1:  # 0 + 1 或 1 + 0
            s.append(1)
            t = 0
        else:  # total == 0
            s.append(0)
            t = 0

        i -= 1  # 继续向左移动
        j -= 1

    if t > 0:  # 如果最后还有进位
        s.append(1)

    # 将二进制转换为十进制
    ans = 0
    for idx in range(len(s)):
        ans += s[idx] * (2 ** idx)  # 计算十进制值

    return str(ans)

我的思考过程

如何设计逐步完善代码

先实现简单的二进制加法:

我从短字符串的加法入手,比如 "101" + "11"。这样可以快速验证加法逻辑是否正确。

添加进位处理:

在实现基本加法后,我加入了进位的处理,观察进位是否正确反映在结果中。

考虑不同长度的字符串:

为了确保算法通用性,我测试了两个长度不等的字符串,并通过补零解决问题。

处理特殊情况:

比如输入全为零,或只有一个字符串有值的情况,确保程序不会报错。

二进制到十进制的难点

对于二进制转十进制,我一开始用 int 函数转换,但后来改用手动实现,因为这样更贴近题目的大数处理要求。

测试与优化

测试用例 设计了测试用例来验证代码的正确性:

    print(solution("101", "110"))  # 结果应该是 "11"(十进制)
    print(solution("111111", "10100"))  # 结果应该是 "83"
    print(solution("111010101001001011", "100010101001"))  # 结果应该是 "242420"
    print(solution("111010101001011", "10010101001"))  # 结果应该是 "31220"

学习收获与建议

从简单开始:

面对复杂问题,先实现一个最简单的版本,比如只处理长度相等的字符串,逐步添加功能。

多测试特殊情况:

遇到问题时,不要急着改代码,可以通过打印中间变量找到错误所在。

关注细节:

比如进位的处理和十进制转换的公式,这些小细节决定了算法是否正确。

学习计划

基础练习:

熟悉二进制与十进制的转换。 编写代码实现简单的二进制加法(例如 "101" + "11")。

进阶练习:

尝试实现大数运算,如多个超长二进制字符串的相加。 研究更高效的二进制运算方法,例如借助位操作优化。

复盘错题:

检查是否遗漏进位的处理。 检查代码是否能正确处理长度差异较大的字符串。