编程之美-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-case全部可能值),空间换时间。

?





2

 

解法五:查表法(预定义结果表),空间换时间。

?





2

 

解法六:二分法(32位)。

两两一组相加,之后四个四个一组相加,接着八个八个,最后就得到各位之和了。

?





2

3

4

5

6

7

8

9

10

int
Count(unsigned x)

{  

    x = x - ((x >> 1) & 0x55555555);   

    x = (x & 0x33333333) + ((x >> 2) & 0x33333333);   

    x = (x + (x >> 4)) & 0x0F0F0F0F;   

    x = x + (x >> 8);   

    x = x + (x >> 16);   

    return
x & 0x0000003F;   

}

?





2

 

解法七:HAKMEM算法。

三个一组,求出每组中1的个数,然后相邻两组归并,得到六个一组的1的个数,最后很巧妙的用除63取余得到了结果。

因为2^6 = 64,也就是说 x_0 + x_1 * 64 + x_2 * 64 * 64 = x_0 + x_1 + x_2 (mod
63),这里的等号表示同余。

这个程序只需要十条左右指令,而且不访存,速度很快。

?





2

3

4

5

6

7

8

9

10

11

12

int
Count(unsigned x)

{

    unsigned n;   

    n = (x >> 1) & 033333333333;   

    x = x - n;  

    n = (n >> 1) & 033333333333;  

    x = x - n;   

    x = (x + (x >> 3)) & 030707070707;  

    x = modu(x, 63); 

    return
x;  

}

?





2

 

其他方法 http://www.cnblogs.com/graphics/archive/2010/06/21/1752421.html

时间: 2024-12-15 07:01:29

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

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

求二进制数中1的个数 继京东618店庆时买的<编程之美>这本书,翻了翻,发现里面的题还是挺有意思的,看起来我们觉得很简单的题目,解法却有很多很多种,真是一个比一个巧妙,于是,决定记录一下. 书中的题目如下 对于一个字节(8bit)的无符号数,求其二进制表示中"1"的个数,要求算法的执行效率尽可能高. 就像书中给我们说的一样,我们一般人可能想到的解决方法如下 int countOne(int n){ int count=0; while(n){ if(n%2==1){ cou

求二进制数中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

【编程之美学习笔记】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的个数

学到的知识点:将一个数和它本身减一作与运算,如果结果为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)的时间求解.

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

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

求二进制数中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) {

编程之美 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) =

近乎O(1)求二进制数中1的个数

以前一直在用很普通的方式求二进制中1的个数 1 int run(int n){ 2 int cnt; 3 while(n>0){ 4 n=n&(n-1); 5 cnt++; 6 } 7 } 普通版 啊我好菜啊 发现大佬都用一种奇奇怪怪的算法 O(1)就解决了这种问题 int bsrun(int n){ int tmp=n - ((n>>1) &033333333333)-((n>>2) &011111111111); return((tmp+(tmp&