9.二进制中1的个数

二进制中1的个数

题目描述

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
这本来是一道简单的位移运算题,但是我却做得问题百出,请看代码后的分析。
class Solution {
public:
     int  NumberOf1(int n) {
         int count = 0 ;
         unsigned int arg = 1 ;
         while ( arg ) {
             if ( n & arg ) {
                 count++ ;
             }
             arg = arg << 1 ;
         }
         return count ;
     }
};
关于位移有4个概念:逻辑左移、算术左移、逻辑右移、算术右移,这4个东西
比如一个有符号位的8位二进制数11001101,逻辑右移就不管符号位,如果移一位就变成01100110。算术右移要管符号位,右移一位变成10100110。
逻辑左移=算数左移,右边统一添0
逻辑右移,左边统一添0
算数右移,左边添加的数和符号有关
e.g:1010101010,其中[]位是添加的数字
逻辑左移一位:010101010[0]
算数左移一位:010101010[0]
逻辑右移一位:[0]101010101
算数右移一位:[1]101010101
1.在本题中我们要移动的是arg,而且是循环的左移arg,虽然逻辑左移和算术左移不会出现补1这样的幺蛾子,但是为了严谨起见,我们把arg的类型设置为unsigned int,意为无符号整形。
2.刚开始我的条件判断是这样写的 if ( n & arg == 1 ),,1在这里表示一个二进制数,该数的最低位为1,其余位全为0,仅n的最低位为1且arg的最低位为1是条件成立,这显然 错误的!
3.arg右移一位时我忘记把右移的值重新赋给arg,直接写的arg << 1; 这也犯了错。

第二次做:
第二次做依然参考了第一次的代码,这里有转换一下思路,输入的参数n不动,对cur做循环左移(算术左移 = 逻辑左移,这是使用左移的主要原因),当cur移动8次后就溢出了,变为0。
class Solution {
public:
     int  NumberOf1(int n) {
         int count = 0 ;
         int cur = 1 ;
         
         while ( cur ) {
             if ( cur & n ) {
                 ++ count ;
             }
             cur = cur << 1 ;
         }
         return count ;
     }
};

第三次做:
class Solution {
public:
     int  NumberOf1(int n) {
         int cur = 1 ;
         int count = 0 ;
         
         while ( cur ) {
            if ( cur & n ) ++ count ;
         	cur = cur << 1 ;	    
         }
         
         return count ;
     }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值