二进制求和

给定两个二进制字符串,返回他们的和(用二进制表示)。

输入为非空字符串且只包含数字 1 和 0。

示例 1:

输入: a = "11", b = "1"
输出: "100"

示例 2:

输入: a = "1010", b = "1011"
输出: "10101"

思路

整体思路是将两个字符串较短的用 000 补齐,使得两个字符串长度一致,然后从末尾进行遍历计算,得到最终结果。

本题解中大致思路与上述一致,但由于字符串操作原因,不确定最后的结果是否会多出一位进位,所以会有 2 种处理方式:

    第一种,在进行计算时直接拼接字符串,会得到一个反向字符,需要最后再进行翻转
    第二种,按照位置给结果字符赋值,最后如果有进位,则在前方进行字符串拼接添加进位

时间复杂度:O(n)

//JAVA
class Solution {
    public String addBinary(String a, String b) {
        StringBuilder ans = new StringBuilder();
        int ca = 0;
        for(int i = a.length() - 1, j = b.length() - 1;i >= 0 || j >= 0; i--, j--) {
            int sum = ca;
            sum += i >= 0 ? a.charAt(i) - '0' : 0;
            sum += j >= 0 ? b.charAt(j) - '0' : 0;
            ans.append(sum % 2);
            ca = sum / 2;
        }
        ans.append(ca == 1 ? ca : "");
        return ans.reverse().toString();
    }
}

 

<think>嗯,用户之前问了关于C++除法的问题,现在又问二进制求和的C++代码,看来他们可能在解决一些编程题目,特别是字符串处理相关的。二进制求和应该是指两个二进制字符串相加,返回它们的二进制字符串。比如“1010”加“1011”结果是“10101”。 首先,我需要回忆一下二进制加法的基本规则。每一位相加会有进位,所以需要考虑当前位的以及进位到高位的值。可能需要从字符串的末尾开始逐位相加,因为二进制的最低位在右边。 接下来,用户可能需要一个高效的解决方案。考虑到C++中字符串的操作,如果从后往前处理,可以使用逆序遍历,或者先将字符串反转,然后从前往后处理会更方便。另外,处理完所有位后,如果有剩余的进位,需要添加到结果中。 然后,代码的结构大致是这样的:初始化结果字符串,设置进位为0,然后循环处理每一位,直到两个字符串都处理完并且没有进位为止。在每一位的处理中,取出当前位的数字(如果存在),加上进位,计算当前位的以及新的进位。然后将当前位的结果插入到结果字符串的前面,或者最后反转结果字符串。 需要注意的是,输入的字符串可能长度不同,所以在处理的时候要判断是否已经处理完较短的字符串。同时,字符到数字的转换可以通过减去'0'来实现,数字到字符则加上'0'。 另外,用户可能希望代码简洁且高效,可能希望避免使用额外的空间,但这里因为字符串需要构建结果,所以必须使用额外的存储。例如,可以使用一个while循环,从两个字符串的末尾开始,逐位相加,直到所有位处理完毕且进位为0。 还要考虑一些边界情况,比如两个字符串都为空,或者其中一个为空,或者相加后有进位导致结果长度增加,比如“1”加“1”应该得到“10”。 可能还需要测试一下代码的确性,比如用示例输入来验证。例如,输入1010”1011”应该得到“10101”。 此外,用户可能对代码中的某些部分不太理解,比如为什么要用reverse,或者如何处理不同长度的字符串。因此,在解释代码的时候需要详细说明每一步的操作,以及为什么这样做。 最后,代码的确性效率是关键。时间复杂度应该是O(max(n, m)),其中nm是两个输入字符串的长度,空间复杂度也是同样的,因为需要存储结果字符串。</think>以下是一个实现二进制求和的高效 C++ 代码示例及详细解析: --- ### 方法原理 从**最低位(字符串末尾)**开始逐位相加,处理进位,最终构造结果字符串。时间复杂度:$O(\max(n,m))$ --- ### 完整代码实现 ```cpp #include <string> using namespace std; string addBinary(string a, string b) { string result; int carry = 0; int i = a.size() - 1, j = b.size() - 1; while (i >= 0 || j >= 0 || carry > 0) { int sum = carry; if (i >= 0) sum += a[i--] - '0'; // 取a的当前位 if (j >= 0) sum += b[j--] - '0'; // 取b的当前位 carry = sum / 2; // 计算进位 result.push_back(sum % 2 + '0'); // 当前位结果 } reverse(result.begin(), result.end()); // 反转得到确顺序 return result; } ``` --- ### 关键步骤解析 1. **双指针逆向遍历**: - `i` 指向字符串 `a` 的末位 - `j` 指向字符串 `b` 的末位 - 同步向字符串头部移动 2. **位运算技巧**: - `sum % 2` 获取当前位的值(0或1) - `sum / 2` 计算进位值(0或1) 3. **处理不同长度字符串**: - 当任一字符串还有未处理的位时继续循环
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值