刷题打卡 | 豆包MarsCode AI 刷题

61 阅读4分钟

二进制字符串求和并返回十进制结果

题目描述

给定两个二进制字符串 binary1binary2,它们可能非常长,需要将这两个二进制字符串相加,并返回其十进制形式的和。算法的时间复杂度要求不超过 (O(n^2)),其中 (n) 是较长字符串的长度。

解题思路

本题的关键在于如何高效处理大数运算。普通的数据类型如 intlong long 无法支持大数的存储和计算,因此需要使用超长整数类型(如 C++ 的 __int128或者使用高精度)来实现大数运算。以下是算法的主要步骤:

  1. 反转字符串:将二进制字符串反转,方便按照权重依次读取每一位进行计算。
  2. 将二进制转换为超长整数
    • 从低位到高位依次遍历二进制字符串的每一位;
    • 如果该位为 1,则将对应的权重 (2^i) 累加到结果中。
  3. 计算二进制和
    • 将两个超长整数相加,得到其十进制的和。
  4. 将结果转换为十进制字符串
    • 通过取模运算和整除运算依次提取结果的每一位,构造十进制字符串。
  5. 返回结果

代码实现

以下是完整的 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;
}

测试结果

  1. 输入binary1 = "101", binary2 = "110"
    输出11
    解释101 表示十进制的 5110 表示十进制的 6,相加得到 11

  2. 输入binary1 = "111111", binary2 = "10100"
    输出83
    解释111111 表示十进制的 6310100 表示十进制的 20,相加得到 83

  3. 输入binary1 = "111010101001001011", binary2 = "100010101001"
    输出242420
    解释:按照同样的逻辑进行二进制到十进制转换并求和。

  4. 输入binary1 = "111010101001011", binary2 = "10010101001"
    输出31220

时间复杂度分析

  1. 字符串反转:需要 (O(n + m)) 时间,(n, m) 为两个字符串的长度。
  2. 二进制转十进制:每个字符串需要 (O(n)) 时间来逐位累加。
  3. 十进制求和:由于使用了超长整数类型,实际加法运算时间复杂度为 (O(1))。
  4. 十进制结果转换为字符串:需要 (O(\log_{10}(c))),其中 (c) 是结果的大小。

因此,整体时间复杂度为 (O(n + m + \log_{10}(c))),满足题目要求。

总结

本题的解法充分利用了 C++ 中的超长整数类型 __int128,避免了常规大数处理时的复杂性。算法逻辑清晰,处理效率高,并能正确应对极长的二进制字符串输入,是处理类似问题的高效方法之一。