求二进制数中1的个数(编程之美)

求二进制数中1的个数

继京东618店庆时买的《编程之美》这本书,翻了翻,发现里面的题还是挺有意思的,看起来我们觉得很简单的题目,解法却有很多很多种,真是一个比一个巧妙,于是,决定记录一下。

书中的题目如下

  • 对于一个字节(8bit)的无符号数,求其二进制表示中“1”的个数,要求算法的执行效率尽可能高。

就像书中给我们说的一样,我们一般人可能想到的解决方法如下

int countOne(int n){
 int count=0;
 while(n){
     if(n%2==1){
         count++;
    }
     n/=2;
 }
 return count;
}

然后,有的人可能说我采用移位的方式来解决,但这种方法与上面的方法随大同小异,但在效率上有很大的提升,这是因为移位操作较除、余操作要快。

文章中提到的第三种方法如下:这种方法实在是很巧妙,想不到

int countThree(int n){
    int count=0;
    while(n){
        n&=(n-1);//与一次就可以消掉n中最右边的“1”,因此也就可以统计出来
        count++;
    }
}

文章中提到的第四种方法:查表法(以空间换取时间),通过空间来换取时间是一个比较常用的方法。

由于8bit的表太长,这里选取的是4bit的表的例子如下

int count_bit4(int n)
{
     int countTable[16] =
    {
        0, 1, 1, 2,
        1, 2, 2, 3,
        1, 2, 2, 3,
        2, 3, 3, 4
    } ;

     int count =0 ;
    while (n)
    {
    /*即将无符号数n以4位为一组进行“1”的查表统计
    */
        count += countTable[n &0xf] ;
        n >>=4 ;
    }
    return count ;
}

根据上面的程序,无论我们的变量n时32为的,还是16为都可以快速的统计出n的二进制数中“1”的个数,这也就解决了《编程之美》2.1节后面的第一个问题。第一个问题如下:

  • 如果变量时32为的DWORD,你会使用上述的哪一种算法,或者改进哪一种算法?

第二题

  • 判断整数A和B的二进制表示中有多少位是不同的?

也比较简单:先进行异或,然后再判断异或所得结果中“1”的个数

时间: 2024-08-02 02:51:18

求二进制数中1的个数(编程之美)的相关文章

编程之美-02数字之魅-求二进制数中1的个数

题目:求二进制数中 1 的个数 对于一个字节(8bit)的无符号整型变量,求其二进制表示中"1"的个数,要求算法的执行效率尽可能地高. 解法一:移位->判断->累计 解法二:除2->判断->累计 解法三:v &= (v -1)需要掌握 ? 2 3 4 5 6 7 8 int num = 0; while(v) {     v &= (v -1);     num++; } return num; ? 2   解法四:分支操作(swicth-cas

求二进制数中1的个数——引发的问题

<编程之美>书中有这样的一道问题“求二进制数中1的个数” 题目:对于一个字节(8bit)的无符号整形变量,求其二进制中“1”的个数,要求算法的执行效率尽可能高. 我使用java语言处理:输出结果是3 public class Count { public static int Count(byte d){ int num = 0; while (d != 0) { d &= (d-1);//比较1的个数 num++; } return num; } public static void

【位运算】求二进制数中1的个数

1 import java.util.Scanner; 2 3 /** 4 * 功能:位运算,求二进制数中1的个数 5 * 思路:通过每次右移一位,并与1进行与运算,判断该位是否是1,最后统计个数. 6 */ 7 public class Main4 { 8 9 public int count(int num) { 10 11 if (num <= 0) { 12 return 0; 13 } 14 15 int count = 0; 16 17 while (num > 0) { 18 i

编程之美----求二进制数中1的个数

学到的知识点:将一个数和它本身减一作与运算,如果结果为0,说明这个数表示成二进制数时里面有且仅有一个1.于是乎,下面这段代码可以用来求一个数中1的个数. 1 int Count(BYTE v) 2 { 3 int num=0; 4 while(v) 5 { 6 v &= (v-1); 7 num++; 8 } 9 return num; 10 } 另外,如果要求的数位数比较小,可以用hash表来做个预处理,这样可以用o(1)的时间求解.

【编程之美学习笔记】2.1求二进制数中1的个数

问题:对于一个字节(8bit)的无符号整型变量,求其二进制表示中“1”的个数,要求算法的执行效率尽可能高. 解法一:除.余操作 我们知道,对于二进制操作,除以一个2,原来的数字将会减少一个0,如果除的过程中有余,那么就表示当前位置有一个1,所以可通过相除和判断余数的值来分析. [时间复杂度O(log2v),log2v为二进制数的位数,空间复杂度O(1)] 1 int Count(int v){ 2 int num = 0; 3 while(v){ 4 if(v % 2 == 1) num++;

求二进制数中1的个数

对于一个字节(8bit)的无符号整型变量,求二进制表示中1的个数. 解法一: 除二求余法,如10100011 除以2 得01010001余1.当除二结果为1时,二进制中1的个数会减少一个,例, 01010001除以2得00101000余1  .当能整除2时,二进制中1的个数不变,例,00101000除以2得00010100. public static int getOneNumber(int num){ int onenum=0; while(num!=0){ if (num%2==1) {

读书笔记一:求二进制数中1的个数

问题描述: 对于一个字节(8bit)的无符号整型变量,求其二进制表示中“1”的个数,要求算法的执行效率尽可能高效. 在编写程序的过程中,根据实际应用的不同,对存储空间或效率的要求也不一样.比如在PC上与在嵌入式设备上的程序编写就有很大的差别. 分析与解法: 解法一: 举一个八位的二进制例子来分析.对于二进制操作,我们知道,除以一个2,原来的数字将会减少一个0.如果除的过程中有余,那么就表示当前位置有一个1. 以10100010为例: 第一次除以2时,商为1010001,余为0. 第二次除以2时,

算法-求二进制数中1的个数

普通法: 我总是习惯叫普通法,因为我实在找不到一个合适的名字来描述它,其实就是最简单的方法,有点程序基础的人都能想得到,那就是移位+计数,很简单,不多说了,直接上代码,这种方法的运算次数与输入n最高位1的位置有关,最多循环32次. int BitCount(unsigned int n) { unsigned int c =0 ; // 计数器 while (n >0) { if((n &1) ==1) // 当前位是1 ++c ; // 计数器加1 n >>=1 ; // 移位

编程之美 2.1 求二进制数中1的个数

如果有数n 曾经用除二取余法 复杂度logn 不多说 有一个logv的方法 v为1的个数 复杂度比logn小 int Count(int x) { int ans = 0; while(x) { x &= (x-1); ans++; } return ans; } 这里用到了位运算  x&(x-1)每次去掉一个1 举个样例 100010001000&(100010001000-1) = 100010000000 100010000000&(100010000000-1) =