题目链接:http://soj.sysu.edu.cn/1201
题目大意:输入两个二进制数,输出相加结果
解题思路:高精度相加
首先,在两个二进制数的前面都补若干个0,使它们的位数相等。注意:即使是长度相等,也要补上一个0,这个是用来存储最高位的进位的。比如:1001和10这两个数,补全后应该是01001,00010;而1100和1001则应该变为01100和01001。
然后,从二进制的最低位(即字符串的最高位)开始依次进行二进制数的相加,如果结果大于1(即10或11),则把最低位(即0或1)保存在答案数组里,然后把进位(即1)加到高位的被加数上。
最后,对存储答案的数组输出。注意要删除前面多余的0
本题需要特别注意的地方就是相加结果为0的时候。刚开始没考虑这个问题导致WA,然后我想到了要考虑0的情况,但是为了避免修改最后输出数组的代码,我只是简单地在最前面判断输入输入字符串是否为“0”的情况,结果又是WA。苦想不出结果后上网搜寻答案,结果发现输入有可能是“000”和“00”等类型的,我前面简单的判断是无法满足这种情况的,于是还是得修改最后的输出,多加一个判断输出0即可。哎,贪图简便不深入思考是不行的啊!
#include <iostream>
#include <string>
using namespace std;
int main()
{
// n 表示测试数据总数
// lengtha、lengthb 分别表示字符串 a、b 的长度
// 字符串 tempa、tempb 表示输入的两个字符串
// 字符串 a、b 分别表示字符串 tempa、tempb 前面补 0 后的字符串
int n, lengtha, lengthb, k;
string a, b, tempa, tempb, temp;
cin >> n;
for (int count = 1; count <= n; count++)
{
int c[81] = {0}; // 用于存储答案
cin >> tempa >> tempb;
cout << count << " ";
/*
// 不能这样写,因为输入有可能是 00 和 00
if (tempa == "0" && tempb == "0")
{
cout << "0" << endl;
continue;
}
*/
// 保证第一个字符串比第二个字符串长
if (tempa.size() < tempb.size())
{
temp = tempa;
tempa = tempb;
tempb = temp;
}
lengtha = tempa.size();
lengthb = tempb.size();
a = "";
b = "";
// 字符串 tempb 前面补 0 操作
for (int i = 0, m = lengtha - lengthb + 1; i < m; i++)
b += '0';
b += tempb; // 获得补 0 后的字符串 tempb
a += '0' + tempa; // 获得补 0 后的字符串 tempa
// 进行二进制相加
for (int i = lengtha; i > 0; i--)
{
c[i] = (a[i] - '0') + (b[i] - '0');
// 如果两个数相加产生进位,则 c[i] 保存最低位,并把进位加到前一位被加数中
if (c[i] > 1)
{
c[i] -= 2;
a[i - 1] += 1;
}
}
c[0] = a[0] - '0'; // 保存最高位的进位
// 输出结果,删除前面多余的 0
for (k = 0; k <= lengtha; k++)
if (c[k] != 0)
{
for (int j = k; j <= lengtha; j++)
cout << c[j];
break;
}
// 如果 a 和 b 相加为 0, c 数组中存储的数全为 0
// 上述循环不会输出,循环结束后 k == lengtha + 1
// 因此要在这里输出 0,否则不会产生输出而导致 WA
if (k == lengtha + 1)
cout << "0";
cout << endl;
}
return 0;
}