二进制字符串求和并返回十进制结果
题目描述
给定两个二进制字符串 binary1 和 binary2,它们可能非常长,需要将这两个二进制字符串相加,并返回其十进制形式的和。算法的时间复杂度要求不超过 (O(n^2)),其中 (n) 是较长字符串的长度。
解题思路
本题的关键在于如何高效处理大数运算。普通的数据类型如 int 或 long long 无法支持大数的存储和计算,因此需要使用超长整数类型(如 C++ 的 __int128或者使用高精度)来实现大数运算。以下是算法的主要步骤:
- 反转字符串:将二进制字符串反转,方便按照权重依次读取每一位进行计算。
- 将二进制转换为超长整数:
- 从低位到高位依次遍历二进制字符串的每一位;
- 如果该位为
1,则将对应的权重 (2^i) 累加到结果中。
- 计算二进制和:
- 将两个超长整数相加,得到其十进制的和。
- 将结果转换为十进制字符串:
- 通过取模运算和整除运算依次提取结果的每一位,构造十进制字符串。
- 返回结果。
代码实现
以下是完整的 C++ 实现代码:
#include <bits/stdc++.h>
using namespace std;
std::string solution(std::string binary1, std::string binary2) {
__int128 a = 0, b = 0;
// 反转二进制字符串,方便从低位开始处理
reverse(binary1.begin(), binary1.end());
reverse(binary2.begin(), binary2.end());
// 转换第一个二进制字符串为十进制超长整数
for (int i = 0; i < binary1.length(); i++) {
if (binary1[i] == '1') {
a += (1LL << i); // 累加当前位对应的权重
}
}
// 转换第二个二进制字符串为十进制超长整数
for (int i = 0; i < binary2.length(); i++) {
if (binary2[i] == '1') {
b += (1LL << i);
}
}
// 计算二进制和
__int128 c = a + b;
// 将结果转换为十进制字符串
std::string s;
while (c) {
s += (c % 10) + '0'; // 提取最低位
c /= 10; // 移除最低位
}
// 结果可能为0,需要特殊处理
if (s.empty()) s = "0";
// 反转字符串,得到最终结果
reverse(s.begin(), s.end());
return s;
}
int main() {
// 测试用例
std::cout << (solution("101", "110") == "11") << std::endl;
std::cout << (solution("111111", "10100") == "83") << std::endl;
std::cout << (solution("111010101001001011", "100010101001") == "242420") << std::endl;
std::cout << (solution("111010101001011", "10010101001") == "31220") << std::endl;
return 0;
}
测试结果
-
输入:
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 = "111010101001011",binary2 = "10010101001"
输出:31220
时间复杂度分析
- 字符串反转:需要 (O(n + m)) 时间,(n, m) 为两个字符串的长度。
- 二进制转十进制:每个字符串需要 (O(n)) 时间来逐位累加。
- 十进制求和:由于使用了超长整数类型,实际加法运算时间复杂度为 (O(1))。
- 十进制结果转换为字符串:需要 (O(\log_{10}(c))),其中 (c) 是结果的大小。
因此,整体时间复杂度为 (O(n + m + \log_{10}(c))),满足题目要求。
总结
本题的解法充分利用了 C++ 中的超长整数类型 __int128,避免了常规大数处理时的复杂性。算法逻辑清晰,处理效率高,并能正确应对极长的二进制字符串输入,是处理类似问题的高效方法之一。