问题描述
小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)初始化进位标志:通常使用一个变量(如
carry)来表示进位,初始值设为0。
(2)逐位相加并处理进位:从最低位(字符串的末尾)开始,逐位相加。如果和大于等于2,则记录进位(carry设为1),并将和的个位作为当前位的结果;否则,不进位(carry保持为0),并将和作为当前位的结果。 (3)传递进位:在处理下一位时,将上一位的进位加到当前位的和中,并重复步骤2。 处理最高位进位:如果遍历完所有位后仍有进位(即carry为1),则需要在结果字符串的最前面添加一位1。 - 结果反转: (1)结果收集:在逐位相加的过程中,将每一位的结果收集到列表中,由于是从最低位开始计算的,所以列表中的第一个元素实际上是最终结果的最低位。 (2)结果反转:将列表中的元素顺序反转过来。
(3)反转后的列表包含了需要的二进制数的每一位,但是它们仍然是分开的字符串。来将这些字符串拼接成一个完整的二进制字符串.
6. 十进制转换:
使用了 reversed 函数来反转 result 列表,然后使用 ''.join 将其拼接成一个字符串。最后,使用 int 函数将这个二进制字符串转换为十进制数,并将其转换为字符串形式返回。
# 找到最长的字符串长度
max_length = max(len(binary1), len(binary2))
# 在左边补0对齐
binary1 = binary1.zfill(max_length)
binary2 = binary2.zfill(max_length)
carry = 0
result = []
# 从右往左进行相加
for i in range(max_length - 1, -1, -1):
b1 = int(binary1[i])
b2 = int(binary2[i])
total = b1 + b2 + carry
# 计算当前位的和和进位
result.append(str(total % 2)) # 直接获取当前位的结果
carry = total // 2 # 获取进位
# 如果有进位剩余,添加到结果中
if carry:
result.append(str(carry))
# 反转结果并转换为十进制数
decimal_result = int(''.join(reversed(result)), 2)
# 将十进制数转换为字符串后返回
return str(decimal_result)
# 测试用例
if __name__ == "__main__":
print(solution("101", "110") == "11")
print(solution("111111", "10100") == "83")
print(solution("111010101001001011", "100010101001") == "242420")
print(solution("111010101001011", "10010101001") == "31220")