题目
给你两个二进制字符串,返回它们的和(用二进制表示)。
输入为 非空 字符串且只包含数字 1 和 0。
思路
要分三种情况,字符串长度相等的(a>b 和 b>a),字符串长度不等的。每次从字符串中各取出一个字符,两个字符和进位相加,有4中情况,余0进0,余1进0,余0进1,余1进1.然后,要在最后面,判断一下进位是否为1,为1的话,还要再最前面添上一位数字。
代码
class Solution {
public String addBinary(String a, String b) {
StringBuffer result=new StringBuffer();//结果
//反转a和b,先反转过来,有利于利用小标进行处理,没反转之前,下标的处理太复杂了
StringBuffer a_temp=new StringBuffer(a);
a=a_temp.reverse().toString();
StringBuffer b_temp=new StringBuffer(b);
b=b_temp.reverse().toString();
int a_length=a.length();
int b_length=b.length();
int c=0;
int d=0;
int carry=0;
if (a_length>b_length)
{
for (int i=0;i<b_length;++i)//公共长度部分
{
c=a.charAt(i)-48;
d=b.charAt(i)-48;
if (c+d+carry<=1)
{
result.append((c+d+carry));
carry=0;
}
else
{
result.append(((c+d+carry)%2));//有可能 1 1 进位也是1
carry=1;
}
}
for (int j=b_length;j<a_length;++j)//非公共部分
{
c=a.charAt(j)-48;
if (c+carry<=1)
{
result.append((c+carry));//余1进0 余0进0
carry=0;
}
else
{
result.append(((c+carry)%2));//余1进1 余0进1
carry=1;
}
}
}
else if (a_length<b_length)
{
for (int i=0;i<a_length;++i)//公共长度部分
{
c=a.charAt(i)-48;
d=b.charAt(i)-48;
if (c+d+carry<=1)
{
result.append((c+d+carry));
carry=0;
}
else
{
result.append((c+d+carry)%2);
carry=1;
}
}
for (int j=a_length;j<b_length;++j)//非公共部分
{
c=b.charAt(j)-48;
if (c+carry<=1)
{
result.append((c+carry));
carry=0;
}
else
{
result.append((c+carry)%2);
carry=1;
}
}
}
else
{
for (int i=0;i<a_length;++i)
{
c=a.charAt(i)-48;
d=b.charAt(i)-48;
if (c+d+carry<=1)
{
result.append(((c+d+carry)%2));
carry=0;
}
else
{
result.append(((c+d+carry)%2));
carry=1;
}
}
}
//最后还有进位的话,要记得补1
if (carry==1)
result.append(1);
return result.reverse().toString();
}
}
结果
其实上面的代码完全可以优化下,判断长度后,长度长的放在前面,长度短的放在后面,就不用有else if 的那段代码,浪费空间。而且这个过程中,要特别主要处理边界的问题。因为这个,我还wa了两次,总是不能够很好的考虑到测试用例的全部方面。
另外的思路
其实这道题,利用一个栈来解答,也许还不用上面那么复杂的逻辑,只是可能速度会比较慢。