思路:
(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;
}
};