题目:输入两个表示二进制的字符串,清计算它们的和,并以二进制字符串的形式输出。 0.核心:
「字符串的第 0 位是最高位,从左往右编号」「要计算从右边(最低位)数起第 3 位」
1.定义:
在二进制里:
- 最左边那一位是最高位(high bit)
- 最右边那一位是最低位(low bit)
2.代码
public class A_AddBinary {
public String addBinary(String a , String b) {//输入参数是两个二进制字符串,返回值是一个字符串
StringBuilder result = new StringBuilder();//创建一个可变字符串,用来存加法的结果
int i = a.length() - 1;//指针 i 和 j 分别指向 a 和 b 的最后一位(最低位;长度没有0,字符串有0位,字符串是‘第一位’,‘第二位’,‘第三位’从左往右排序
int j = b.length() - 1;
int carry = 0;//初始化进位,刚开始是 0
while (i >= 0 || j >= 0) {//当 a 和 b 还有任何一方没遍历完,就继续循环
int digitA = i >= 0 ? a.charAt(i--) - '0' : 0;//`a.charAt(i)` 是取 a 字符串第 i 位上的字符,比如 '1' 或 '0'。 `'1' - '0'` 结果是数字 1;'0'-'0' 是数字 0
int digitB = j >= 0 ? b.charAt(j--) - '0' : 0;//如果 i 或 j 小于 0(说明已经没数字了),就用 0 来代替。同时:i-- / j-- 会让指针向左移动一位
int sum = digitA + digitB + carry;//digitA + digitB + carry,总和可能是 0/1/2/3,不会有4
carry = sum >= 2 ? 1 : 0;//确定新的进位,如果总和 ≥2,就要进位 1;否则进位是 0
sum = sum >=2 ? sum - 2 : sum;//把sum变成这一位的数字(0或1)
result.append(sum);//注意这里是从低位往高位加,所以最后需要反转
}
if (carry == 1) {//循环结束后,检查还有没有剩余进位
result.append(1);//如果最后还有进位,把它加上
}
return result.reverse().toString();//因为是从低位开始加的,要反转一下。要 `reverse()` 反过来,再用 `toString()` 变成字符串返回
}
public static void main(String[] args) {
A_AddBinary obj = new A_AddBinary();
String result = obj.addBinary("111","10");
System.out.println("Result: " + result);
}
}
3.举例子:
a = "111"
b = "10"
从右往左加、carry 和反转的全过程
准备:
- a 长度 3 → i=2
- b 长度 2 → j=1
- carry=0
- result=空
第一次循环(最低位)
i=2, j=1
- a[2]='1' → digitA=1
- b[1]='0' → digitB=0
- sum=1+0+0=1
- sum<2 → carry=0
- append(1)
现在:
- result="1"
- i=1, j=0
第二次循环:
i=1, j=0
- a[1]='1' → digitA=1
- b[0]='1' → digitB=1
- sum=1+1+0=2
- sum≥2 → carry=1
- sum=2-2=0
- append(0)
现在:
- result="10"
- i=0, j=-1
第三次循环:
i=0, j=-1
- a[0]='1' → digitA=1
- b 没有了 → digitB=0
- carry=1
- sum=1+0+1=2
- sum≥2 → carry=1
- sum=0
- append(0)
现在:
- result="100"
- i=-1, j=-2
循环结束后,carry=1:
- carry>0 → append(1)
- result="1001"
因为是从右往左加的,需要反转:
result.reverse() → "1001" → "1001"
反转后还是 "1001"