#include<iostream>
using namespace std;
/*
Description: 解法一:求余法,时间复杂度O(lgn)
以10100010为例:
第一次除以2时,商为1010001,余数为0;
第二次除以2时,商为101000,余数为1;
......
故,可以利用整形数据除法的特点,通过相除判断余数的值来分析。有如下代码:
*/
int getNum1(int n)
{
if(n==0) return 0;
int count=0;
while(n)
{
if(n%2==1)
{
count++;
}
n/=2;
}
return count;
}
/*
Description: 解法二:与0x01进行&操作,再移位 ,时间复杂度O(lgn)
以10100010为例:
10100010,第一次&0x01时,结果为0,右移1位;
1010001,第二次&0x01时,结果为1右移1位;
......
故,可以利用此特点,通过相"与"判断结果的值来分析。有如下代码:
*/
int getNum2(int n)
{
if(n==0) return 0;
int count=0;
while(n)
{
count+=n&1;
n>>=1;
}
return count;
}
/*
Description: 解法三:与(n-1)相"与",时间复杂度少于O(lgn)=O(m)
以10100010为例:
10100010,第一次&0x01时,结果为0,右移1位;
1010001,第二次&0x01时,结果为1右移1位;
......
故,可以利用此特点,通过相"与"判断结果的值来分析。有如下代码:
*/
int getNum3(int n)
{
if(n==0) return 0;
int count=0;
while(n)
{
n&=(n-1);
count++;
}
return count;
}
/*
Description: 解法四:查表法 ,时间复杂度少于O(1)
以空间换时间
一个字节的无符号整型数据范围就在[0,255]之间,因此可以直接定义一个长度为256的数组table[0-255],
把0-255二进制表示中1的1的个数赋给数组的元素,这样直接进行查找
有如下代码:
*/
int table[256]={
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
};
int getNum4(int n)
{
return table[n];
}
//动态打表
int getNum41(int n)
{
// 建表
unsigned char BitsSetTable256[256] = {0} ;
// 初始化表
for(int i=0;i<256;++i)
{
BitsSetTable256[i]=(i&1)+BitsSetTable256[i/2];
}
unsigned int count = 0 ;
// 查表
unsigned char *p=(unsigned char *)&n;
count=BitsSetTable256[p[0]] +
BitsSetTable256[p[1]] +
BitsSetTable256[p[2]] +
BitsSetTable256[p[3]];
return count ;
}
int main()
{
int n;
while(cin>>n)
{
cout<<getNum1(n)<<endl;
cout<<getNum2(n)<<endl;
cout<<getNum3(n)<<endl;
cout<<getNum4(n)<<endl;
cout<<getNum41(n)<<endl;
}
system("pause");
return 0;
}