问题描述
将两个二进制字符串相加,并以十进制形式返回求和结果。由于二进制字符串可能非常长,不能直接转换为十进制求和。因此,需要设计一个时间复杂度不超过 (O(n^2)) 的算法来处理大数二进制字符串相加,并输出十进制的和。
问题分析
这道题的关键在于如何处理二进制数的大数相加问题。我们可以将二进制字符串逐位模拟相加,计算出二进制结果后,再将该二进制字符串转换为十进制数。这一过程可以分为以下几个步骤:
- 二进制字符串对齐:将两个输入字符串通过补零对齐,使得二进制长度一致,便于逐位相加。
- 逐位相加:从低位到高位逐位相加。
- 进位处理:逐位相加时,记录进位,并保存下来并用于下次加法操作。
- 二进制转十进制:将得到的相加结果(仍是一个二进制字符串)转换成十进制数。
解题思路
solution
主函数,负责将两个二进制字符串相加并返回十进制结果。具体操作包括:
- 字符串补零对齐:获取两个二进制字符串的长度,将较短的字符串用
zfill补零,使其与较长字符串等长,从而便于逐位相加。 - 逐位调用
plus函数相加:从最低位开始(从右至左),逐位调用plus函数来对当前位及进位进行加和,结果保存在sum列表中。 - 记录进位:
plus函数返回当前位的和与进位,进位用于下一个更高位的加法计算,最终的最高位进位也会记录在sum列表中。 - 调用
binary_decimal函数转换十进制:最终计算完成的二进制结果保存在sum中,调用binary_decimal函数将sum转换为十进制数并返回。
binary_decimal
binary_decimal 函数将二进制字符串转换为十进制,主要使用指数乘法的原理逐位相加完成转换。具体操作包括:
- 从最高位到最低位遍历二进制字符串。
- 对于每一位,如果该位是
'1',则将其按位权值(对应的 (2^{位置}))乘积加入sum中。 - 最终得到的
sum即为该二进制字符串对应的十进制值。
plus
plus 函数执行逐位加和操作,并根据加和结果计算当前位的值和进位。具体流程如下:
- 将二进制位
c1、c2和进位add转换为整数后求和,结果存储在sum中。 - 根据
sum的值来判断返回结果:sum == 3时,当前位为'1',进位为'1'。sum == 2时,当前位为'0',进位为'1'。sum == 1时,当前位为'1',无进位。sum == 0时,当前位为'0',无进位。
- 返回当前位的计算结果和进位,用于下一位的加和。
代码实现
import math
def solution(binary1, binary2):
max_len = max(len(binary1), len(binary2))
# 对齐二进制字符串长度
binary1 = binary1.zfill(max_len)
binary2 = binary2.zfill(max_len)
# 初始化结果列表,用于存储相加结果
sum = ['0'] * (max_len + 1)
add = '0'
# 从最低位向高位逐位相加
for i in range(max_len - 1, -1, -1):
c1 = binary1[i]
c2 = binary2[i]
# plus 函数计算当前位结果与进位
sum[i + 1], add = plus(c1, c2, add)
# 将最终进位放入结果的最高位
sum[0] = add
# 将二进制结果转换为十进制
result = binary_decimal(sum)
return str(result)
def binary_decimal(string):
# 将二进制字符串转十进制
sum = 0
for i in range(len(string)):
alpha = len(string) - i - 1
if string[i] == '1':
sum += math.pow(2, alpha)
return int(sum)
def plus(c1, c2, add):
# 将字符转换为整数以便相加
c1, c2, add = int(c1), int(c2), int(add)
# 三数相加判断结果和进位
sum = c1 + c2 + add
if sum == 3:
return '1', '1' # 当前位为1,进位为1
elif sum == 2:
return '0', '1' # 当前位为0,进位为1
elif sum == 1:
return '1', '0' # 当前位为1,无进位
else:
return '0', '0' # 当前位为0,无进位
复杂度分析
- 时间复杂度:在
solution函数中,字符串对齐、逐位相加和二进制转十进制的步骤都为 (O(n)) 复杂度,其中 (n) 是较长的二进制字符串的长度。因此,总体时间复杂度为 (O(n))。 - 空间复杂度:由于需要存储与输入字符串等长的结果列表,因此空间复杂度为 (O(n))。
可优化方向
- 二进制转十进制:
binary_decimal函数中使用幂运算来计算每个位的权重值。可以通过左移操作实现从二进制到十进制的直接转换,从而提高效率。 - 进位优化:在
plus函数中,根据不同情况下的三位相加,直接返回进位结果的逻辑可以优化为字典查表方式,减少条件判断的分支开销。
总结与收获
本题通过模拟二进制字符串的逐位相加,解决了大数二进制相加的问题。笔记中对逐位相加、进位和二进制转十进制等操作进行了详细解释,帮助理解大数处理方法。通过题解学习了如何有效地对齐和遍历字符串,利用数学操作将二进制转十进制并输出结果。