解题报告: 二进制之和 | 豆包MarsCode AI刷题

107 阅读5分钟

问题描述

小U和小R对二进制数字充满兴趣,希望找到一种方法,将两个任意长度的二进制字符串相加,并将结果以十进制形式输出。由于输入可能非常长,直接使用传统的整数计算方法可能会出现溢出或性能问题。因此,需要设计一个能够手动处理大数的算法,在保证时间复杂度不超过 O(n2)O(n^2) 的前提下解决问题。


输入与输出

输入:两个二进制字符串 binary1binary2,每个字符串长度均不超过 100,且仅包含字符 '0''1'

输出:一个字符串形式的十进制数,表示两个输入二进制字符串的和。


解题思路

为了解决这个问题,需要分以下几个步骤实现:

1. 二进制字符串转十进制字符串

将二进制字符串转化为十进制字符串需要模拟手动计算的过程:

  • 从左到右遍历二进制字符串。
  • 每处理一位,当前十进制结果乘以 2(相当于左移一位),如果当前位是 '1',则加 1。
  • 由于结果可能非常大,使用字符串来表示十进制数,避免溢出。

2. 十进制字符串加法

为了加法的通用性,手动实现两个十进制字符串的加法:

  • 从两个字符串的最低位开始逐位相加,同时处理进位。
  • 使用一个列表存储每一位的计算结果,最后反转得到最终的正确顺序。

3. 二进制字符串的相加

在完成了二进制到十进制的转换和十进制字符串加法的实现后:

  • 先将两个二进制字符串分别转为十进制字符串。
  • 再通过十进制字符串加法计算最终结果。

算法实现

以下是具体实现的 Python 代码:

def add_strings(num1, num2):
    """
    将两个十进制字符串相加,并返回结果字符串。
    """
    res = []
    carry = 0
    p1 = len(num1) - 1
    p2 = len(num2) - 1

    while p1 >= 0 or p2 >= 0 or carry:
        x1 = int(num1[p1]) if p1 >= 0 else 0
        x2 = int(num2[p2]) if p2 >= 0 else 0
        total = x1 + x2 + carry
        carry = total // 10
        res.append(str(total % 10))
        p1 -= 1
        p2 -= 1

    return ''.join(res[::-1])

def multiply_by_two(num):
    """
    将一个十进制字符串乘以2,并返回结果字符串。
    """
    res = []
    carry = 0
    for digit in reversed(num):
        temp = int(digit) * 2 + carry
        carry = temp // 10
        res.append(str(temp % 10))
    if carry:
        res.append(str(carry))
    return ''.join(res[::-1])

def binary_to_decimal(bin_str):
    """
    将二进制字符串转换为十进制字符串。
    """
    dec_str = '0'
    for bit in bin_str:
        dec_str = multiply_by_two(dec_str)
        if bit == '1':
            dec_str = add_strings(dec_str, '1')
    return dec_str

def binary_sum(binary1, binary2):
    """
    计算两个二进制字符串的和,并返回十进制结果字符串。
    """
    dec1 = binary_to_decimal(binary1)
    dec2 = binary_to_decimal(binary2)
    return add_strings(dec1, dec2)

测试样例

为验证算法的正确性,设计了多组测试样例,包括普通情况、边界情况和特殊情况。

输入输出解释
binary1 = "101", binary2 = "110"'11'二进制 101 等于十进制 5,二进制 110 等于十进制 6,相加结果为 11
binary1 = "111111", binary2 = "10100"'83'二进制 111111 等于十进制 63,二进制 10100 等于十进制 20,相加结果为 83
binary1 = "111010101001001011", binary2 = "100010101001"'242420'两个超长二进制数的计算,验证程序的准确性和大数处理能力。
binary1 = "11", binary2 = "1"'4'简单二进制加法,验证短输入时的正确性。

时间复杂度分析

  1. 二进制转十进制
    每个二进制字符串转化为十进制时,需要遍历二进制字符串的每一位。对于每一位,都涉及一个乘法和一个加法操作。假设输入长度为 nn,则单次转换的时间复杂度为 O(n2)O(n^2)(因为十进制字符串操作的复杂度与当前字符串长度成正比)。

  2. 十进制加法
    加法操作的时间复杂度与两个十进制字符串的长度相关,为 O(n)O(n)。

  3. 总复杂度
    二进制字符串的转换和十进制加法是依次进行的。综合来看,整个算法的时间复杂度为 O(n2)O(n^2)。


空间复杂度分析

  1. 额外空间
    主要使用了字符串存储中间结果,空间复杂度为 O(n)O(n)。

  2. 总空间复杂度
    转换和加法过程中不会使用额外的复杂数据结构,空间复杂度为 O(n)O(n)。


总结与反思

算法评价

  • 优点:通过字符串模拟计算,可以有效处理超长输入,解决了传统整数计算可能出现的溢出问题。
  • 缺点:二进制到十进制的转换过程较为耗时,存在进一步优化的空间。

拓展思考

  • 此算法不仅适用于二进制字符串,还可以拓展到其他进制(如八进制、十六进制)的转换与加法问题。
  • 可以研究更高效的字符串运算方法,进一步降低时间复杂度,例如借助更高级的数论方法。

示例运行

# 示例测试
print(binary_sum("101", "110"))  # 输出: "11"
print(binary_sum("111111", "10100"))  # 输出: "83"
print(binary_sum("111010101001001011", "100010101001"))  # 输出: "242420"
print(binary_sum("11", "1"))  # 输出: "4"