剑指offer_面试题10_二进制中1的个数(位运算)

题目:请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如把 9 表示成二进制 1001,有 2 个 1。因此如果输入9,该函数输出2。 

位运算基本概念:

五种位运算:与(&)、或(|)、异或、左移 和 右移。

ps:其中 异或(运算符 ^),1 ^ 0 = 1;   1 ^ 1 = 0;  0 ^ 0 = 0; 0 ^ 1 = 1;  即 相同为假,不同为真。

左移运算符 <<,m << n,表示将 m 向左移动 n 位,并且 最左边的 n 位被丢弃,同时最右边补上 n 个 0。比如

00001010 << 2 = 001010 00;   // 最左边两位被丢弃,最右边两位 补 0;

10001010 << 3 = 01010 000

右移运算符 >>,m >> n,表示将 m 向右移动 n 位,并且 最右边的 n 位被丢弃。但最左边的补植比较复杂,分补0 和 补1,比如

00001010 >> 2 = 00 000010;   // 无符号数,最右边两位被舍弃,最左边两位 补0;

10001010 >> 3 = 111 10001;   // 有符号数,最高位为1,表示是负数,因此 最右边三位被舍弃,最左边三位 补1;

常规解法:(不要用 右移运算来求解,因为若是 有符号数,会补1)

[cpp]  view plain  copy
  1. /*关键值flag,通过左移运算来求解,多少位循环多少次*/  
  2. int Numberof1(int n)  
  3. {  
  4.     int count = 0;  
  5.     unsigned int flag = 1;  
  6.     while(flag)  
  7.     {   
  8.         if(n & flag)     /** 0000 0001 ==> 0000 0010 ==> 0000 0100 ==> ...通过值 1 的那一位的移动(并且进行与运算)来判断 n 中 1 的个数 */  
  9.             count++;  
  10.         flag = flag << 1;  
  11.     }  
  12.     return count;  
  13. }  


惊喜解法:

将一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0。

[cpp]  view plain  copy
  1. /** n & (n - 1) 操作会将 n 最右边的一个 1 变为0,可以通过举例来理解*/  
  2. int Numberof2(int n)  
  3. {  
  4.     int count = 0;  
  5.     while(n)  
  6.     {  
  7.         count++;  
  8.         n = n & (n - 1);  
  9.     }  
  10.     return count;  
  11. }  

相关题目:

1、用一条语句判断一个整数是不是 2 的整数次方。

答:若一个数是 2 的整数次方,那其二进制表示中,有且只有一位是 1。使用 n&(n-1)

2、输入两个整数 m 和 n,计算需要改变 m 的二进制表示中的多少位才能得到 n。

答:举例,使用 异或运算,统计异或结果中 1 的个数。

/*点滴积累,我的一小步O(∩_∩)O~*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值