LintCode 179-更新二进制位

本人电子系,只为一学生。心喜计算机,小编以怡情。


给出两个32位的整数N和M,以及两个二进制位的位置i和j。写一个方法来使得N中的第i到j位等于M(M会是N中从第i为开始到第j位的子串)

样例
给出N = (10000000000)2,M = (10101)2, i = 2, j = 6
返回 N = (10001010100)2


感悟:
1.原本以为很简单的事情,但是如果对二进制的原码补码运算不熟悉,会有很多坑,比如测试数据里有-1,补码表示是11111111111111111111111111111111。
2.然后就是各种下表越界,各种debug。
3.然后发现自己对Java的库了解太少,应该有更方便的内置函数,但我并不知道。。。


思路:将n中要替换的部分减去,得到类似二进制xxxxx0000xxxx的效果
然后将m加到上面,比如1011变成1011xxxx,再加到n上,得到的就是答案。

public int updateBits(int n, int m, int i, int j) {
            // write your code here
     ///////////////////////////////////
     //    得到1011xxxx的效果
         for(int k=0;k<i;k++)
             m*=2;
     ///////////////////////////////////    
     //将n,m转成二进制表示
         StringBuffer temp1=new StringBuffer(Integer.toBinaryString(n));
         StringBuffer temp2=new StringBuffer(Integer.toBinaryString(m));
     ///////////////////////////////////
//   因为下面要给字符串前面补零,因此提前保存相关长度
         int r=temp1.length();
         int t=j-i+1;
     ///////////////////////////////////
    // 只有整数需要补零
    //补零的原因是为了解决当n=1,m=1011,i=2,j=5时,
    //接下来下面的substring提取子串会报错(下标)
    //当然,你也可以用其他的更好的方法,比如动态补零,或者干脆不补零
    //用其他的方法
         if(n>=0)
             for(int k=0;k<32-r;k++)
                 temp1.insert(0, "0");
         if(m>=0)
             for(int k=0;k<32-t;k++)
                 temp2.insert(0, "0");
 ///////////////////////////////////
 //这一步就是提取n中要被取代的那部分子串,然后左移(尾部补零)        
         StringBuffer a=new StringBuffer(temp1.substring(temp1.length()-i-t, temp1.length()-i));
         for(int k=0;k<i;k++)
             a.append("0");
//// ///////////////////////////////
//你可以用int试一试,测试某个数据会报错
         int count=0;
         long sum=0;
 ///////////////////////////////////
 //这里应该有简便的函数   ,将二进制字符串转化为十进制int型   
         for(int k=a.length()-1;k>=0;k--)
         {
             sum+=Math.pow(2, count++)*Integer.parseInt(a.charAt(k)+"");
         }
 ///////////////////////////////////
 //返回就是n-要被替代的那部分+m      
        return (int) (n-sum+m);
     }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值