您的位置:首页 > 其它

十进制整数如何利用位操作求的该整数的二进制中1的个数

2012-03-16 20:46 232 查看
此题可有多种方法,大概可以分为两种:一种是制表法,另一种就是通俗的数学方法。其中数学方法中一个简单明了的方法就是利用一个while循环,采用按位与的方式。代码如下:

#include<iostream>
using namespace std;
int main()
{
	int a;
	int count;
	while(cin>>a&&a)
	{
		count=0;
		while(a>0)
		{
			a=(a-1)&a;
			count++;
		}
		cout<<count<<endl;
	}	
	return 0;
}


但是此代码有一个致命的缺陷,就是当输入数字是负数时,输出结果都是0。改进方案如下:

#include<iostream>
using namespace std;
int main()
{
	int a;
	int count;
	while(cin>>a&&a)
	{
		count=0;
		while(a)
		{
			if(a&1==1)
			{
				count++;
			}
			a=a>>1;
		} 
		cout<<count<<endl;
	}	
	return 0;
}


此思路较为清晰,方法就是每次都查看该十进制数末尾是否为1,如果是count++,如果不是,将最后一位右移。然后再比较下一位。

另一种比较难理解的方法是:

#include<iostream>
using namespace std;
int fun(int x)
{
    x = (0x55555555 & x) + ((0xAAAAAAAA & x)>>1); 
    x = (0x33333333 & x) + ((0xCCCCCCCC & x)>>2);
    x = (0x0F0F0F0F & x) + ((0xF0F0F0F0 & x)>>4);
    x = (0x00FF00FF & x) + ((0xFF00FF00 & x)>>8);
    x = (0x0000FFFF & x) + ((0xFFFF0000 & x)>>16);
    return x;
}
int main()
{
	int a;
	int count;
	while(cin>>a&&a)
	{
		cout<<fun(a)<<endl;
	}	
	return 0;
}


采用打表法的代码如下:

#include<iostream>
#include<cmath>
#include<ctime>
using namespace std;
int f1(int n,int *a)
{//右移四位,与15进行与运算并查表
    int i=0;
    i+=a[n&15];
    i+=a[n>>4&15];
    i+=a[n>>8&15];
    i+=a[n>>12&15];
    i+=a[n>>16&15];
    i+=a[n>>20&15];
    i+=a[n>>24&15];
    i+=a[n>>28&15];
    return i;
}
int f3(int n,int *a)
{//右移八位,与255进行与运算并查表
    int i=0;
    i+=a[n&255];
    i+=a[n>>8&255];
    i+=a[n>>16&255];
    i+=a[n>>24&255];
    return i;
}
int main(void)
{
    // 计算一整数对应二进制数的1的个数
    int i,N;
    int a[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}; //0-255对应二进制数含1的个数
        int b[16]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4}; //0-15对应二进制数含1的个数
    N=20000000;
    double start,finish;
    srand((unsigned int)time(NULL));
    start=clock();
    for(i=0;i<N;++i)
    {
        f1(i,b);
    }
    cout<<i<<endl;
    finish=clock();
    cout<<(finish-start)/CLOCKS_PER_SEC<<endl;
    start=clock();
    for(i=0;i<N;++i)
    {
        f3(i,a);
    }
    cout<<i<<endl;
    finish=clock();
    cout<<(finish-start)/CLOCKS_PER_SEC<<endl;
    return 0;
}




#include<iostream>
using namespace std;
int fun(int x)
{
    x = (0x55555555 & x) + ((0xAAAAAAAA & x)>>1); 
    x = (0x33333333 & x) + ((0xCCCCCCCC & x)>>2);
    x = (0x0F0F0F0F & x) + ((0xF0F0F0F0 & x)>>4);
    x = (0x00FF00FF & x) + ((0xFF00FF00 & x)>>8);
    x = (0x0000FFFF & x) + ((0xFFFF0000 & x)>>16);
    return x;
}
int main()
{
	int a;
	int count;
	while(cin>>a&&a)
	{
		cout<<fun(a)<<endl;
	}	
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: