问题描述
小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'
思路分析
- 字符串对齐:确保两个二进制字符串长度一致,通过补零实现。
- 逐位相加:从右向左遍历字符串,逐位相加并考虑进位。
- 处理进位:记录每一位相加后的进位。
- 结果转换:将得到的二进制字符串结果反转,并转换为十进制字符串。
# 找到最长的字符串长度
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
# 更新当前位的和和进位
if total >= 2:
result.append(str(total % 2)) # 当前位的和(0或1)
carry = total // 2 # 进位(0或1)
else:
result.append(str(total)) # 当前位的和(只能是0或1)
carry = 0 # 没有进位
# 如果有进位剩余,添加到结果中
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") # 样例1
print(solution("111111", "10100") == "83") # 样例2
print(solution("111010101001001011", "100010101001") == "242420") # 样例3
print(solution("111010101001011", "10010101001") == "31220") # 样例4
print(solution("11", "1") == "4") # 样例5
- 字符串对齐:使用
zfill方法在较短的二进制字符串左侧补零,使得两个字符串的长度一致,方便进行逐位相加。 - 初始化:设置一个进位变量
carry,初始值为 0,并创建一个空的结果列表result用于存储每一位的相加结果。 - 逐位相加:从右往左遍历两个对齐后的字符串,将对应位的二进制数字转换为整数进行相加,并加上上一个位置可能存在的进位。根据求得的和更新结果列表和进位变量。
- 处理进位:在遍历结束后,检查是否还有剩余的进位。如果有,则将其添加到结果列表中。
- 结果转换:将结果列表中的字符串反转并连接成一个完整的二进制字符串,随后使用
int函数转换为十进制数字(指定基数为2),最后将其转回字符串格式返回。
个人思考
这个问题展示了使用二进制特性简化大数相加的方法,通过逐位相加提高效率,尤其适用于处理非常长的二进制字符串。此外,这也突显了字符串处理技巧的重要性,尤其是在输入长度不一致的情况下如何有效对齐和补零。通过这个过程,我们能够更深入理解二进制运算规则,并在编程中灵活运用。