二进制中1的个数——使用过滤器

例:求解 a = 1001 0011

一、在做这种题之前我们要知道 & 按位与这个符号,1 与上任何数都不变,0与上任何数都变为0

  32位机器上 我们将过滤器设置以下几种

  两位两位一组(一个1),共16  01 01 01 01 01 ....                                 int m_1 = 0x55555555

  四位四位一组(两个1 ,共8  0011 0011 ...                                          int m_2 = 0x33333333

  88个一组(四个1)一共4  00001111...                                             int m_4 = 0x0f0f0f0f

 1616个一组(八个1)一共2 0000000011111111                               int m_8 = 0x00ff00ff

 32个一组 161 共一对      00000000000000001111111111111111  int m_16 = 0x0000ffff      

二、解题步骤

1)先把a m_1 过滤器过滤一遍  a&(m-1) 

2)然后把 a >>1 再过滤一遍

3)然后把(1)(2)得到的结果加起来 a & (m_1) + ((a>>1) & (m_1)) 

三、代码展示:

#include<iostream>
using namespace std;

int CountOnenumber(int a)
{
	int m_1 = 0x55555555;
	int m_2 = 0x33333333;
	int m_4 = 0x0f0f0f0f;
	int m_8 = 0x00ff00ff;
	int m_16 = 0x0000ffff;

	int b = (a & m_1) + ((a>>1) & m_1);
	int c = (b & m_2) + ((b>>2) & m_2);
	int d = (c & m_4) + ((c>>4) & m_4);
	int e = (d & m_8) + ((d>>8) & m_8);
	int f = (e & m_16) + ((e>>16) & m_16);

	return f;
}

int main()
{
	int a;
	cout<<"请输入:"<<endl;
	cin>>a;
	cout<<CountOnenumber(a)<<endl;
	return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值