Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
给定两个 01 字符串
a和b,请计算它们的和,并以二进制字符串的形式输出。输入为 非空 字符串且只包含数字1和0。
此题要求解两个二进制字符串的和,那么我们可以采用二进制加法的形式,对两个二进制数的每一位进行相加,并考虑进位,最终得到结果。
举个例子,1与111相加,首先我们将长度更短的二进制进行一个填充,使得两个二进制数长度相同:
011
111
这样便可以进行二进制的加法了,对两个二进制数进行从右往左的遍历,让最后一位数相加得到结果2,此时产生进位,所以最后一位的结果为0;接着让倒数第二位数相加,再加上进位得到结果3,此时也产生进位,且该位置的结果为1;最后让第一位数相加,再加上进位得到结果2,所以此位置结果为0,因为有进位,所以结果前面再补个0,最后的结果为1010。
由此可知,我们需要记录一下当前位置的两个数相加是否为产生进位,在计算当前位置结果时,若是产生了进位,让结果取模2即可,若是没有产生进位,得到的结果就是当前结果。
代码如下:
public static String addBinary(String a, String b) {
StringBuilder result = new StringBuilder();
char[] charsA = a.toCharArray();
char[] charsB = b.toCharArray();
int maxLen = Math.max(charsA.length, charsB.length);
int minLen = Math.min(charsA.length, charsB.length);
char[] charsTempA = new char[maxLen];
char[] charsTempB = new char[maxLen];
// 对长度更短的二进制数进行填充
if (charsA.length > charsB.length) {
for (int i = 0; i < maxLen - minLen; ++i) {
charsTempB[i] = '0';
}
System.arraycopy(charsB, 0, charsTempB, maxLen - minLen, minLen);
charsTempA = charsA;
} else {
for (int i = 0; i < maxLen - minLen; ++i) {
charsTempA[i] = '0';
}
System.arraycopy(charsA, 0, charsTempA, maxLen - minLen, minLen);
charsTempB = charsB;
}
boolean flag = false;
// 遍历
for (int i = 1; i <= maxLen; ++i) {
// 当前位置的两数相加
int num = Integer.parseInt(charsTempA[charsTempA.length - i] + "") + Integer.parseInt(charsTempB[charsTempB.length - i] + "");
// 若产生进位,结果加1
if (flag) {
num++;
}
// 若相加结果大于等于2,则说明产生进位
if (num >= 2) {
// 当前结果为相加结果取模2
result.append(num % 2);
// 标记进位标志位true
flag = true;
} else {
// 若无进位则直接添加结果
result.append(num);
// 标记进位标志位false
flag = false;
}
}
// 若循环结束仍然有进位,则额外添加一个1
if (flag) {
result.append(1);
}
// 反转字符串得到结果
return result.reverse().toString();
}
此题得解。