码迷,mamicode.com
首页 > 其他好文 > 详细

2016.5.16——leetcode:Number of 1 Bits ,

时间:2016-05-15 17:59:56      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:

leetcode:Number of 1 Bits

1.Number of 1 Bits

本题收获:

  1.Hamming weight:即二进制中1的个数

  2.n &= (n-1)【n = n & (n-1)】的用处

  题目:

  Write a function that takes an unsigned integer and returns the number of ’1‘ bits it has (also known as the Hamming weight).

  For example, the 32-bit integer ’11‘ has binary representation 00000000000000000000000000001011, so the function should return 3.

  思路:

  我的思路:

    遍历字符串1的个数,(疑问,数字转换成字符串的具体操作)

  leetcode/discuss思路:

    n &= n-1,将二进制n与n-1按位与,有几个1将循环几次。这种方法效率最高。

  代码:

 1 class Solution {
 2 public:
 3    int hammingWeight(uint32_t n) {
 4     int count = 0;
 5 
 6     while (n) 
 7     {
 8         n &= (n - 1);    //即为n = n&n(n-1),联想n += 1为n = n+1
 9         count++;
10     }
11 
12     return count;
13     }
14 };

碎碎念(不清楚的知识点):

一。n&(n-1)作用:将n的二进制表示中的最低位为1的改为0,先看一个简单的例子:
  n = 10100(二进制),则(n-1) = 10011 ==》n&(n-1) = 10000
  可以看到原本最低位为1的那位变为0。
  弄明白了n&(n-1)的作用,那它有哪些应用?
  1). 求某一个数的二进制表示中1的个数
    while (n >0 )

      {

        count ++;
            n &= (n-1);
       }

  2). 判断一个数是否是2的方幂
  n > 0 && ((n & (n - 1)) == 0 )

  

二.to_string是将整型转换成字符串型,具体怎么用还不清楚:http://www.cplusplus.com/reference/string/to_string/可以参考这个链接

 

三.运算符

  按位与运算符(&)

    参加运算的两个数据,按二进制位进行“与”运算。

    运算规则:0&0=0;   0&1=0;    1&0=0;     1&1=1;

        即:两位同时为“1”,结果才为“1”,否则为0。

      例如:3&5  即 0000 0011 & 0000 0101 = 0000 0001   因此,3&5的值得1。

     负数按补码形式参加按位与运算。

    “与运算”的特殊用途:

      (1)清零。如果想将一个单元清零,即使其全部二进制位为0,只要与一个各位都为零的数值相与,结果为零。

      (2)取一个数中指定位

          方法:找一个数,对应X要取的位,该数的对应位为1,其余位为零,此数与X进行“与运算”可以得到X中的指定位。

          例:设X=10101110,

              取X的低4位,用 X & 0000 1111 = 0000 1110 即可得到;

            还可用来取X的2、4、6位。

 

  按位或运算符(|)

    参加运算的两个对象,按二进制位进行“或”运算。

    运算规则:0|0=0;   0|1=1;   1|0=1;    1|1=1;

        即 :参加运算的两个对象只要有一个为1,其值为1。

        例如:3|5 即 0000 0011 | 0000 0101 = 0000 0111   因此,3|5的值得7。 

      负数按补码形式参加按位或运算。

    “或运算”特殊作用:

    (1)常用来对一个数据的某些位置1。

    方法:找到一个数,对应X要置1的位,该数的对应位为1,其余位为零。此数与X相或可使X中的某些位置1。

    例:将X=10100000的低4位置1 ,用 X | 0000 1111 = 1010 1111即可得到。

  异或运算符(^)

    参加运算的两个数据,按二进制位进行“异或”运算。

    运算规则:0^0=0;   0^1=1;   1^0=1;   1^1=0;

      即:参加运算的两个对象,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。

    “异或运算”的特殊作用:

      (1)使特定位翻转 找一个数,对应X要翻转的各位,该数的对应位为1,其余位为零,此数与X对应位异或即可。

      例:X=10101110,使X低4位翻转,用X ^ 0000 1111 = 1010 0001即可得到。

      (2)与0相异或,保留原值 ,X ^ 0000 0000 = 1010 1110。

  取反运算符(~)

    参加运算的一个数据,按二进制位进行“取反”运算。

    运算规则:~1=0;   ~0=1;

        即:对一个二进制数按位取反,即将0变1,1变0。

    使一个数的最低位为零,可以表示为:a&~1。

      ~1的值为1111111111111110,再按“与”运算,最低位一定为0。因为“~”运算符的优先级比算术运算符、关系运算符、逻辑运算符和其他运算符都高。

  左移运算符(<<)

    将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。

    例:a = a << 2 将a的二进制位左移2位,右补0,

      左移1位后a = a * 2; 

    若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2

  右移运算符(>>)

    将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。

    操作数每右移一位相当于原操作数除2

     例如:a = a >> 2 将a的二进制位右移2位,

     左补0 or 补1 得看被移数是正还是负。

  无符号右移运算符(>>>)

  >> 运算符把 expression1 的所有位向右移 expression2 指定的位数。expression1 的符号位被用来填充右移后左边空出来的位。向右移出的位被丢弃。

    例如,下面的代码被求值后,temp 的值是 -4:

      -14 (即二进制的 11110010)右移两位等于 -4 (即二进制的 11111100)。

     var temp = -14 >> 2

  复合赋值运算符

  位运算符与赋值运算符结合,组成新的复合赋值运算符,它们是:

    &=    例:a &= b        相当于a=a & b

    |=    例:a |= b        相当于a=a | b

    >>=   例:a >>= b       相当于a=a >> b

    <<= 例:a <<= b       相当于a=a << b

    ^=   例:a ^= b       相当于a=a ^ b

  运算规则:和前面讲的复合赋值运算符的运算规则相似。

如果两个不同长度的数据进行位运算时,系统会将二者按右端对齐,左边补0,然后进行位运算

  

 

2016.5.16——leetcode:Number of 1 Bits ,

标签:

原文地址:http://www.cnblogs.com/zhuzhu2016/p/5495634.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!