zoukankan      html  css  js  c++  java
  • 2016.5.15——leetcode:Number of 1 Bits ,

    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.

      notice:输入的数字是十进制,是对十进制进行判断

      思路:

      我的思路:

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

      leetcode/discuss思路:

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

      代码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 };

      我的代码:带有main函数

     1 #include "stdafx.h"
     2 #include "iostream"
     3 #include "stdint.h"    //uint32_t的头函数
     4 using namespace std;
     5 
     6 class MyClass
     7 {
     8 public:
     9     int hanminweight(uint32_t n)
    10     {
    11         int count = 0;
    12 
    13         while(n != 0)
    14         {
    15             n = n & (n-1);
    16             count++;
    17             //cout << count << endl;测试
    18             //cout << n << endl;
    19         }
    20         return count;
    21     }
    22 };
    23 
    24 
    25 
    26 int _tmain(int argc, _TCHAR* argv[])
    27 {
    28     MyClass solution;
    29     int m;
    30     uint32_t nums;
    31     cin >> nums ;
    32     m = solution.hanminweight(nums);
    33     cout << "the number of 1bits is:" << m << endl;
    34     //cin.get();    //不知道为什么cin.get()不可以了??
    35     system("pause");
    36     return 0;
    37 }

       代码2:开始讲题意理解错了,误以为输入为二进制,现在重新写了个输入为二进制的代码。

     1 #include "stdafx.h"
     2 #include "iostream"
     3 #include <string>    //string的头文件
     4 #include "stdint.h"    //uint32_t的头函数,这里可以不用
     5 using namespace std;
     6 
     7 class Binary
     8 {
     9 public:
    10     int hanminweightbinary(string s)
    11     {
    12         int nums = 0;
    13         for (size_t i = 0; i < s.size(); i++)
    14         {
    15             //cout << s[i] << endl;        //测试
    16             if (s[i] == '1')        //在字符串中判断时数字为整型1 应该为‘1’此为字符串,if (s[i] == 1) 出错,nums始终为0
    17             {
    18                 ++nums;
    19             }
    20             //cout << nums << endl;
    21         }
    22         return nums;
    23     }
    24 };
    25 
    26 int _tmain(int argc, _TCHAR* argv[])
    27 {
    28     Binary solution;    //若想要多次循环可以加while(true)语句
    29     int m;
    30     string str;
    31     cin >> str;
    32     m = solution.hanminweightbinary(str);
    33     cout << "the number of 1bits is:" << m << endl;
    34     //cin.get();    //不知道为什么cin.get()不可以了??
    35     system("pause");
    36     return 0;
    37 }

    调试过程中出错:

      错误1:error C2679: 二进制“<<”: 没有找到接受“std::string”类型的右操作数的运算符(或没有可接受的转换)

      原因:没有加string的头文件#include <string>

      错误2:nums的值始终为0

      原因:if (s[i] == 1)  应该为 if (s[i] == '1')

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

    一。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,然后进行位运算

      

  • 相关阅读:
    SQL Server Profiler使用方法
    RichTextBox控件-主要用于输入输出编辑文本信息
    ComboBox
    另一个 SqlParameterCollection 中已包含 SqlParameter
    GUID全局唯一标识符
    MDI-多文档窗体
    【转】classpath和环境变量设置
    接口、抽象类都要单建(好习惯)
    Java基础部分回顾(为自己)
    Java基础——ArrayList与LinkedList(二)
  • 原文地址:https://www.cnblogs.com/zhuzhu2016/p/5495634.html
Copyright © 2011-2022 走看看