剑指 Offer II 002. 二进制加法

文章介绍了如何处理大数的二进制字符串相加问题,避免数据溢出。方法包括字符串反转、逐位相加和处理进位,最后再反转得到结果。提供的代码示例展示了两种不同的实现方式,一种利用反转和一位一位的加法,另一种则是补零和逐步判断进位。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

思路:
(1)因为如果给的是大数,直接转换成十进制会出现 数据溢出的情况,所以我们要直接对字符串进行处理。
(2)主要分为三步:对齐,模拟加法,输出

    先将两个数据进行反转,使得低位对应小顺序,高位对应大顺序。这样相加之后再反转,就和原本的值是一样的。这里的问题是反转后,小的那个数据在访问大坐标的时候为什么不越界呢?直接访问是越界的,但是做判断的时候,却可以判断是不是为1
    采用了一个很巧妙的carry,就这一个变量就能决定本位和是否进位。判断a,b当前位是否为1,为1的话carry就+1,这样两个1carry就为2,对2来取余来决定本位是1还是0。再将carry/2来判断是否有进位。
    最后计算完再反转数据。

class Solution {
public:
    string addBinary(string a, string b) {
        string ans;
        reverse(a.begin(), a.end());
        reverse(b.begin(), b.end());
        int a_len = a.size(), b_len = b.size();
        int n = max(a_len, b_len);
        int carry = 0;
        for (int i = 0; i < n; ++i) {
            carry += i < a_len ? a.at(i) == '1' : 0;
            carry += i < b_len ? b.at(i) == '1' : 0;
            ans.push_back(carry % 2 ? '1' : '0');
            carry /= 2;
        }
        if (carry) {
            ans.push_back('1');
        }
        reverse(ans.begin(), ans.end());
        return ans;
    }
};

    最后再写一个自己写的代码,思路是一样的,就是对数据反转的时候,我选择了直接对差位的数据进行补0,在求本位和进位的时候也比较麻烦,选择了逐步判断,这样太浪费时间和空间了。

class Solution {
public:
    string addBinary(string a, string b) 
    {
        string sum;
        int lena = a.size();
        int lenb = b.size();
        if (a.size() > b.size()) 
        {
            for (int i = 0;i < lena-lenb;i++)
            {
                b.insert(0, "0");
            }
        }
        else
            for (int i = 0;i < lenb - lena;i++)
            {
                a.insert(0, "0");
            }

        int len = a.size();
        int add = 0;

        int i = len - 1;

         for (i;i >= 0;i--)
        {
            if (add == 0)
            {
                if (a[i] == '0' && b[i] == '0')
                    sum.push_back('0');
                else if ((a[i] == '1' && b[i] == '0') || a[i] == '0' && b[i] == '1')
                    sum.push_back('1');
                else
                {
                    sum.push_back('0');
                    add = 1;
                }
                continue;
            }

            if (add == 1)
            {
                if (a[i] == '0' && b[i] == '0')
                {
                    sum.push_back('1');
                    add = 0;
                }
                else if ((a[i] == '1' && b[i] == '0') || a[i] == '0' && b[i] == '1')
                {
                    sum.push_back('0');
                    add = 1;
                }
                else
                {
                    sum.push_back('1');
                    add = 1;
                }
                continue;
            }

        }
         if (add == 1)
         {
             sum.push_back('1');
         }


         reverseStr(sum);
        return sum;
    }

    string reverseStr(string& str)
    {
        int n = str.length();

        // Swap character starting from two 
        // corners 
        for (int i = 0; i < n / 2; i++)
            swap(str[i], str[n - i - 1]);

        return str;
    }

};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值