计算一个整数的二进制中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.

  

  对于这个问题,我们首先想到是将十进制数转换成二进制的过程,通过除2取余来得到二进制的每一位来判断。然后,最容易想到的方法肯定不是最好的算法,我们可以考虑有没有比这个方法更好的算法。我们自然想到,通过移位操作要比出发操作的效率高很多。

  位操作算法:首先将整数n与0x01做位与运算(&),然后将n右移移位,直到将所有位数全部移完。这种方法虽然比上一种好,但执行次数是整数的位数,那有没有一种执行次数是1的个数呢?答案是肯定的。

  我们通过消除最后边的1来操作(n&=(n-1)),很多博客都介绍了这种方法,而我则侧重介绍该方法的原理:可以设想一下,假如n只有一个1的情况,做减1操作会对进行借位或者直接减掉,那么做n&(n-1)的结果则为零,因为n-1后,相对于n原来1的位置发生了改变。那么n有多个1的情况,在第一个1的左边是不会变得的,每次只会影响右边第一个1,情况和之前一样,这个,操作数就为1的个数。

  代码如下,自己写了测试程序(这个小习惯可能会在你面试时写代码的时候发挥奇效呢)。

import java.util.Random;
public class NumberOf1Bit {
/**
 * 转换成2进制数,去比较每一位的值来判断是否为1
 * @param n 输入的一个32位整数
 * @return count 记录1的个数
 */
    public int hammingWeight1(int n){
        int count=0;
        while(n!=0){
            if(n%2!=0)
                count++;
            n/=2;
        }
        return count;
    }
/**
 * 使用移位操作,效率要高于除法运算
 * @param n
 * @return
 */
    public int hammingWeight2(int n){
        int count=0;
        while(n!=0){
            if((n&0x01)!=0)
                count++;
            n>>=1;
        }
        return count;
    }
/**
 * 前两个的运算次数都是每个整数的全部位,下面的方法则只需计算次数由1的个数决定
 * @param n
 * @return
 */
    public int hammingWeight3(int n){
        int count=0;
        while(n!=0){
            if(n!=0)
                count++;
            n&=(n-1);
        }
        return count;
    }
    public void test(){
        Random r = new Random();
        for(int i=0;i<10;i++){
            int n=r.nextInt(50);
            System.out.println(n+"------"+Integer.toBinaryString(n));
            System.out.println(hammingWeight1(n)+"  "+hammingWeight2(n)+"  "+hammingWeight3(n));
            System.out.println("**********");
        }
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new NumberOf1Bit().test();
    }

}

  

时间: 2024-10-16 12:29:20

计算一个整数的二进制中1的个数的相关文章

求一个整数的二进制中1的个数

题目:输入一个整数,求该整数的二进制表达中有多少个1.例如输入10,由于其二进制表示为1010,有两个1,因此输出2. 假设该整数为i.首先i和1做与运算,判断i的最低位是不是为1.接着把1左移一位得到2,再和i做与运算,就能判断i的次高位是不是1……这样反复左移,每次都能判断i的其中一位是不是1.基于此,我们得到如下代码 int NumberOf1_Solution(int i) { int count = 0; unsigned int flag = 1; while(flag) { if(

一个整数对应二进制中1的个数

#include <stdio.h> #include <stdlib.h> /* 4.统计一个整数对应的二进制数的1的个数. 输入一个整数(可正可负), 输出该整数的二进制包含1的个数, “ctl+ z” 结束. */ int main(){ int number; while (scanf("%d", &number) != EOF){ int num[100] = {0}; int length = 0; if (number < 0) nu

统计一个整数的二进制中1的个数

方法一: 比较暴力的方法(通过将二进制右移获得): int _Count(int x) { int cnt = 0; while(x) { cnt += x&1; x >>= 1; } return cnt; } 方法二: 通过这个数与比他小1的数相与得到:(很神奇的一个方法,手动写几个例子就可以看出来了,不过要自己想的话,还是比较费力的) int _Count(int x) { int cnt = 0; while(x) { x &= (x-1); cnt++; } retu

Java之一个整数的二进制中1的个数

这是今年某公司的面试题: 一般思路是:把整数n转换成二进制字符数组,然后一个一个数: private static int helper1(int i) { char[] chs = Integer.toBinaryString(i).toCharArray(); int res = 0; for (int j = 0; j < chs.length; j++) { if (chs[j] == '1') { res++; } } return res; } 第二种方法是:将整数n与1进行与运算,

说一说,求一个正整数的二进制中0的个数

昨天突然看到一个算法题:一个正整数a的二进制中0的个数: 话说这是个老题了,直观的算法就每次右移一位,直到0为止:代码就省略了: 仔细想想有更好的方案么? 就是这个题可以转换成一个正整数~a的二进制中1的个数: 求1的个数这个貌似就很熟悉了吧: int num = 0; b = ~a; while(b){ num++; b = b & (b-1); } 是不是容易了许多呢 另外像java和python这种没有unsigned的语言要自己去转 b = ~a & 0x0ffff

[ACM] POJ 3252 Round Numbers (一个区间内二进制中0的个数大于等于1的个数有多少个,组合)

Round Numbers Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8590   Accepted: 3003 Description The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, Paper, Stone' (also known as 'Rock, Paper, Scissors',

写一个参数返回二进制中1的个数

#include<stdio.h> int main()  {  int num;  int s=0,yus=0,count=0; printf("请输入一个数字:");  scanf("%d",&num);  for(s=num;s>=1;)  {  yus=s%2;  s=s/2;  if (yus==1)  {  count++;  }  }  printf("%d\n",count);  return 0;  }

C++求一个十进制的二进制中1的个数

int oneNumInBinary(int n){ int cnt=0; while(n){ n = n&(n-1); cnt++; } return cnt; }

计算二进制中1的个数

问题:计算某个数的二进制中1的个数 思路:x = x & (x-1) 将 x 的二进制最右面的一个 1 变为 0,其余保持不变.反复操作,直到变为 0 为止,计算操作次数,即为 x 的二进制中 1 的个数. 证明:假设 x 的二进制末尾为 10...0 [末尾有 k 个 0,k = 0,1,2,...]. 则 x - 1 的二进制末尾 k+1 位为 01...1 [末尾有 k 个 1,k = 0,1,2,...],其他与 x 相同. 从而 x & (x-1) 的末尾 k+1 位为 00..