0
点赞
收藏
分享

微信扫一扫

剑指 Offer II 002. 二进制加法(二进制运算)

船长_Kevin 2022-01-05 阅读 66

题目链接
二进制的位运算只有6种:非(!)、与(&)、或(|)、异或(^)、左移(<<)和右移(>>)。

注意

  • 机器中,数的二进制都是存的补码
  • 异或运算^是相异为1,相同为0
  • 在左移<<运算中,正数与负数相同。计算 a < < 3 a <<3 a<<3时,在 a a a的最右边添加3个0即可。
  • 在右移>>运算中,正数与负数不同。计算 a > > 3 a >>3 a>>3时,若 a a a为正数,在 a a a的最左边添加3个0即可;若 a a a为负数,由于 a a a的最高位符号位为1,右移时在 a a a的最左边添加3个1。
  • 无符号右移位操作符>>>,无论是对正数还是负数进行无符号右移操作时,都将在最左边插入0。

思路

  • 若是先将二进制转换为十进制,再来进行加法运算,由于不知道二进制位数的长度,转换为十进制可能会导致溢出。因此,这里直接进行二进制数的相加。
  • 二进制数每个位上只能是0或1,因此产生的进位最高为1。从最低位开始相加,逢2进1。若长度不齐,自动在字符串前面补0。
  • 相加的时候会出现三种情况:1.1+1=2;2.1+0=1;3.0+0=0;再分别判断进位为1或0的情况。

代码

public class p1 {
    public String addBinary(String a, String b) {
        StringBuilder ans = new StringBuilder(); //相加之后形成的二进制字符串
        int len_a = a.length()-1;
        int len_b = b.length()-1;
        int value = 0;//初始的进位为0
        while(len_a >= 0 || len_b >= 0) {
            char ca = len_a >=0 ? a.charAt(len_a--) : '0';
            char cb = len_b >=0 ? b.charAt(len_b--) : '0';//当长度小于0时,用'0'代替当前位
            if(ca-'0' + cb-'0' > 1) {//相加为2
                if(value > 0) {//进位为1
                    ans.append('1');//将1追加到新的字符串里
                    value = 1;//当前进位为1
                } else {//进位为0
                    ans.append('0');
                    value = 1;
                }
            } else if(ca-'0' + cb-'0' == 1){ //1或0
                if(value > 0) {//1
                    ans.append('0');
                    value = 1;
                } else {//0
                    ans.append('1');
                    value = 0;
                }
            } else if(ca-'0' + cb-'0' == 0){//0
                if(value > 0) {//1
                    ans.append('1');
                    value = 0;
                } else {//0
                    ans.append('0');
                    value = 0;
                }
            }
            //System.out.println(ans.toString()+" value="+value+" lena="+len_a+" lenb="+len_b);
        }
        if(value == 1)//若进位还剩1,继续追加
            ans.append(value);
        return ans.reverse().toString();//由于从最低为相加开始进行的追加字符串,真正的字符串还需要再反转
    }

Java知识

  • String 与 StringBuffer的区别
  1. 当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。
  2. 和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
  3. 在使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,所以如果需要对字符串进行修改推荐使用 StringBuffer。StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。
  • 字符串的反转
    StringBuffer().reverse().toString()
  • StringBuffer() -> String()
    StringBuffer().toString()
  • 返回字符串下标为index的字符
    String().charAt()
举报

相关推荐

0 条评论