求二进制数中1的个数

#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;
}
posted @ 2013-04-02 09:47  一枚程序员  阅读(466)  评论(0编辑  收藏  举报