• 求二进制数中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;
    }
  • 相关阅读:
    图片上传-下载-删除等图片管理的若干经验总结3-单一业务场景的完整解决方案
    图片上传-下载-删除等图片管理的若干经验总结2
    HDU 1195 Open the Lock
    HDU 1690 Bus System
    HDU 2647 Reward
    HDU 2680 Choose the best route
    HDU 1596 find the safest road
    POJ 1904 King's Quest
    CDOJ 889 Battle for Silver
    CDOJ 888 Absurdistan Roads
  • 原文地址:https://www.cnblogs.com/sooner/p/2994844.html
Copyright © 2020-2023  润新知