您的位置:首页 > 职场人生

整数的二进制表示中1的个数 【微软面试100题 第二十八题】

2014-10-30 17:22 281 查看
题目要求:

  输入一个整数,求该整数的二进制表示中有多少个1.

  例如输入10,由于其二进制表示作为1010,有两个1,因此输出2.

  参考资料:剑指offer第10题、编程之美2.1

题目分析:

  方法1 除2取余法:一个数a%2的值为0或者1,根据是a的二进制表示的最低位为0,则前面结果为0;【取模和取余的效率比较低。】

  方法2 位操作法:例如a = 0011,a先与0x01&操作,得到一个1,然后a右移为0001,再与0x01&操作,又得到一个1,求和为2;

  方法3 查表法:把所有可能的值放到一个数组中,只要输入一个就直接查表即可。这样时间复杂度为O(1)。【这种方法对于8位的比较方便,如果是16位、32位、、、要建立这个数组就非常麻烦了。因此这种方法的算法只适用于需要频繁使用的地方,通过空间复杂度来换取时间复杂度。

  方法4 [b]Hamming weight(汉明重量):先用2位存储邻近2位里面的1的个数,然后合并,用4位表示邻近4位里面的1的个数,再合并、、、[/b]

[b]

#include <stdio.h>

int BitCount3(unsigned int n) ;

int main(void)
{
printf("bits = %d\n",BitCount3(0xffff));
return 0;
}

int BitCount3(unsigned int n)
{
// 建表
unsigned char BitsSetTable256[256] = {0} ;
int i;
unsigned int c =0 ;
unsigned char* p;

// 初始化表
for (i =0; i <256; i++)
{
BitsSetTable256[i] = (i &1) + BitsSetTable256[i /2];
}

// 查表
printf("%d\n",&n);
//这里很重要,先取地址(此时为32位的地址),然后强制转换为char型(8位)的
p = (unsigned char*) &n ;
printf("&p[0] = %d\n",&p[0]);
printf("p[0] = %d\n",p[0]);
printf("&p[1] = %d\n",&p[1]);
printf("p[1] = %d\n",p[1]);

c = BitsSetTable256[p[0]] +
BitsSetTable256[p[1]] +
BitsSetTable256[p[2]] +
BitsSetTable256[p[3]];

return c ;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: