二进制中1的个数

二进制中1的个数

统计二进制中1的个数可以直接移位再判断,当然像《编程之美》书中用循环移位计数或先打一个表再计算都可以。本文详细讲解一种高效的方法。以34520为例,可以通过下面四步来计算其二进制中1的个数二进制中1的个数。

第一步:每2位为一组,组内高低位相加

      10 00 01 10  11 01 10 00

  -->01 00 01 01  10 01 01 00

第二步:每4位为一组,组内高低位相加

      0100 0101 1001 0100

  -->0001 0010 0011 0001

第三步:每8位为一组,组内高低位相加

      00010010 00110001

  -->00000011 00000100

第四步:每16位为一组,组内高低位相加

      00000011 00000100

  -->00000000 00000111

这样最后得到的00000000 00000111即7即34520二进制中1的个数。类似上文中对二进制逆序的做法不难实现第一步的代码:

       x = ((x & 0xAAAA) >> 1) + (x & 0x5555);

好的,有了第一步,后面几步就请读者完成下吧,先动动笔再看下面的完整代码:

  1. //二进制中1的个数  by MoreWindows( http://blog.csdn.net/MoreWindows )   
  2. #include <stdio.h>  
  3. template <class T>  
  4. void PrintfBinary(T a)  
  5. {  
  6.     int i;  
  7.     for (i = sizeof(a) * 8 - 1; i >= 0; --i)  
  8.     {  
  9.         if ((a >> i) & 1)  
  10.             putchar('1');  
  11.         else   
  12.             putchar('0');  
  13.         if (i == 8)  
  14.             putchar(' ');  
  15.     }  
  16.     putchar('\n');  
  17. }  
  18. int main()  
  19. {  
  20.     printf("二进制中1的个数 --- by MoreWindows( http://blog.csdn.net/MoreWindows )  ---\n\n");  
  21.       
  22.     unsigned short a = 34520;  
  23.     printf("原数    %6d的二进制为:  ", a);  
  24.     PrintfBinary(a);  
  25.       
  26.     a = ((a & 0xAAAA) >> 1) + (a & 0x5555);  
  27.     a = ((a & 0xCCCC) >> 2) + (a & 0x3333);  
  28.     a = ((a & 0xF0F0) >> 4) + (a & 0x0F0F);  
  29.     a = ((a & 0xFF00) >> 8) + (a & 0x00FF);     
  30.     printf("计算结果%6d的二进制为:  ", a);     
  31.     PrintfBinary(a);  
  32.     return 0;  
  33. }  
//二进制中1的个数  by MoreWindows( http://blog.csdn.net/MoreWindows ) 
#include <stdio.h>
template <class T>
void PrintfBinary(T a)
{
	int i;
	for (i = sizeof(a) * 8 - 1; i >= 0; --i)
	{
		if ((a >> i) & 1)
			putchar('1');
		else 
			putchar('0');
		if (i == 8)
			putchar(' ');
	}
	putchar('\n');
}
int main()
{
	printf("二进制中1的个数 --- by MoreWindows( http://blog.csdn.net/MoreWindows )  ---\n\n");
	
	unsigned short a = 34520;
	printf("原数    %6d的二进制为:  ", a);
	PrintfBinary(a);
	
	a = ((a & 0xAAAA) >> 1) + (a & 0x5555);
	a = ((a & 0xCCCC) >> 2) + (a & 0x3333);
	a = ((a & 0xF0F0) >> 4) + (a & 0x0F0F);
	a = ((a & 0xFF00) >> 8) + (a & 0x00FF);	
	printf("计算结果%6d的二进制为:  ", a);	
	PrintfBinary(a);
	return 0;
}

运行结果如下:

可以发现巧妙运用分组处理确实是解决很多二进制问题的灵丹妙药。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值