• 剑指offer-面试题10:二进制中1的个数


    题目:请实现一个函数,输入一个函数,输出该数二进制表示中1的个数。例如把9

    表示成二进制是1001,有2位是1.因此如果输入9,该函数输出2.

    这道题最典型的方法就是用移位统计,就比如统计9的二进制1个数:

    1.9的二进制位1001,9-1的二进制位1000.

    2.两者做与运算,结果为1表示最后一位为1,否则为0

    3.将1001向右移位一位然后重复上述步骤直到该数字为0停止

    代码实现如下:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int NumberOf1(int n)
     5 {
     6     int count=0;
     7     while(n)
     8     {
     9         if(n&1)
    10             count++;
    11         n=n>>1;
    12     }
    13     return count;
    14 }
    15 
    16 
    17 int main(int argc, char* argv[])
    18 {
    19     int number;
    20     cout<<"Please input the Number: ";
    21     cin>>number;
    22     cout<<"count '1': "<<NumberOf1(number)<<endl;
    23     return 0;
    24 }

    运行截图:

    但是有个问题,这种方法不适合负数

    因为负数的右移位后最高位的符号位仍然需要保留。

    剑指offer一书提供一种方法:

    其思路是这样:

    1.首先取一个flag整数,并且让flag=1;

    2.让flag&number 如果为1则证明最低位为1

    3.flag<<1 同时flag&number 如果为1则证明次低位为1.

    4.知道flag移位了sizeof(number)*8次便完成统计。

    说明:flag的数据类型应与number的数据类型一致。

    这种方法实现如下:

     1 int NumberOf1(int n)
     2 {
     3 
     4     int count=0;
     5     unsigned int flag=1;
     6     while(flag)
     7     {
     8         if(n&flag)
     9             count++;
    10 
    11         flag=flag<<1;
    12     }
    13     return count;
    14 }

    运行结果:

    其实我们可以分析一下负数在内存中存储方式:

    以-9为例,将设int战4个字节

    原码:1000 0000|0000 0000|0000 1001

    补码(原码除符号位之外取反加1):1111 1111|1111 1111|1111 0111

    我们既然是这样我们可以对负数来说:

    1.先取负数的相反数-number,此时-number>0

    2.-number-1,同时让-number-1按照方法1的方式右移位计算count

    3.取sizeof(num)*8-count即为负数在内存中存储的1的个数

    验证代码如下:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int NumberOf1(int n)
     5 {
     6 
     7     int count=0;
     8     n=n-1;
     9     while(n)
    10     {
    11         if(n&1)
    12             count++;
    13         n=n>>1;
    14     }
    15 
    16     count=sizeof(n)*8-count;
    17     
    18     return count;
    19 }
    20 
    21 
    22 int main(int argc, char* argv[])
    23 {
    24     int number;
    25     cout<<"Please input the Number: ";
    26     cin>>number;
    27     cout<<"count '1': "<<NumberOf1(-number)<<endl;
    28     return 0;
    29 }

    验证结果:

  • 相关阅读:
    LeetCode 368Largest Divisible Subset
    macbook 源码安装 redis6.2.6
    macbook 源码安装 nginx1.20.1
    MySQL总结
    DataWork之 MaxComputer的使用
    Spring的IOC源码分析
    Spring Bean的生命周期
    SpringMVC工作原理
    Spring全家桶(二)之SpringMVC总结
    (已经成功部署)配置vue+nginx+uwsgi luffy项目
  • 原文地址:https://www.cnblogs.com/vpoet/p/4670674.html
Copyright © 2020-2023  润新知