【算法】二进制中1的个数

195 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第6天,点击查看活动详情

题目

实现一个函数输入一个整数,输出该数二进制表示中1的个数。例如9表示成二进制是1001,有2位是1,因此如果输入是9,输出就是2。

PS:在Java中&是按位与,例如运算数值是int类型时会先将两侧数转化为二进制数再进行运算。举例12&5,12转二进制是1100,,5转二进制是0101,他们与运算后就是0100,用十进制表示就是数值4。

解题思路

二进制循环遍历法

结合提示中的算法,&运算可将十进制数转化为二进制。可通过遍历方式判断输入值从右到左一共有几个值是1的,因此只要把输入值和1做位与运算即可(每次循环1先做位运算再和输入值做与运算)。

 int ret = 0;
 /// int整数二进制是32位的 因此位移数32次
 for (int i = 0; i < 32; i++) { 
     if ((n & (1 << i)) != 0) { // 遍历检查每一位数值是不是1 
         ret++; // 值如果为1则+1计数
     }
 }
 return ret;

与运算进阶解法

首先分析一个数减去1是什么样的情况。如果整数不等于0,其二进制表示至少有一位是1。举例数的最右边一位是1,当该数减去1时最后一位变成0,而其他位不变。依次类推只要是一个数减1操作,从右到左最先找到的1变为0,变1的右边所有0变成1。

例如1100减1操作后变成1011,再减去1则变为1010

此时1100和1011做与运算则变成1000,可见可以通过该方式计算出一个数的二进制1的数量。把一个数减去1,再和原数做与运算就能判断该原数是否有1。

int res = 0;
while(n != 0) { // 判断数中是否没有1了(除0以外的整数中肯定还有1
    res++;  // 有1就++
    n &= n - 1;  // 剔除最靠右的一个1
} 
return res;