题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数,例如把9表示成二进制是1001,有2位是1,因此如果输入9,该函数输出2.
思路
1,一般做法,对2除法取余,但是效率较低,除法的效率比移位运算低很多,在实际编程中尽可能地用移位运算符代替乘除法
2,右移位,当负数时,如0x8000移位结果为0xC000,这样就会造成死循环
3,左移位,常规,用标示符1,10,100,1000,....分别于n做与运算,根据结果判断,n个位,十位,百位,千位,....是否为1
4,最佳算法,不好想到,首先要明白这样一个规则,把一个整数(二进制)减去1,都是把最右边的1变成0,如果它的右边还有0的话,所有的0都变成1,而它左边所有位都保持不变。接着,把一个整数和它减去1的结果做位与运算,相当于把这个原数的最右边的1变成了0,换种说法,就是找到了一个最右边的1,并且替换成了0,这样继续寻找,直到结束。
源代码:
#include "stdio.h"
#include "stdlib.h"
//一般方法效率低
int count(int n)
{
int count=0,a;
while(n!=0)
{
a=n%2;
n=n/2;
if(a==1)
count++;
}
return count;
}
//左移,常规
int NumberOf(int n)
{
int count=0;
int flag=1;
while(flag)
{
if(n&flag)
count++;
flag=flag<<1;
}
return count;
}
//右移,当n为负数死循环出错,不可取
int NumberOf1(int n)
{
int count =0;
while(n)
{
if(n&1)
count++;
n=n>>1;
}
return count;
}
//最佳
int NumberOf2(int n)
{
int count=0;
while(n)
{
count++;
n=(n-1)&n;
}
return count;
}
int main()
{
int n;
printf("输入:");
scanf("%d",&n);
int result;
result=count(n);
printf("输出:%d\n",result);
printf("左移:%d\n",NumberOf(n));
printf("最佳:%d\n",NumberOf2(n));
int x=9;
int y=10;
printf("与运算:%d",x&y);
return 0;
}
结果
输入:9
输出:2
左移:2
最佳:2
与运算:8