面试题15:二进制中1的个数
题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1。因此如果输入9,该函数输出2。
#include <iostream>
#include <cmath>
using namespace std;
/**
* 方法一:首先我们的想法通过对n进行位运算,该方法对正数还是非常有效的,
* 但是对于负数的时候,向右移动的时候最高为不能设为0,而是应该设置为1,
* 这个方法会陷入死循环。(待修改)
**/
int NumberOf1(int n) {
int count=0;
while(n){
if(n&1) count++;
n=n>>1; // 可以用除以2?答案是否定的,因为除法的效率比移位运算效率低
}
return count;
}
/**
* 方法二:我们不对n进行位运算,而是对flag进行向左的位运算,但是这个方法循环的次数
* 等于整数二进制的位数,32位的整数需要循环32次, 对于正负n都可以。
**/
int NumberOf2(int n){
int count=0;
unsigned int flag=1;
while(flag){
if(n&flag) count++;
flag=flag<<1;
}
return count;
}
/**
* 方法三:令人惊艳的解法
* 利用n和(n-1)与操作,能够得到n去掉最右边的1的结果
**/
int NumberOf3(int n){
int count=0;
while(n){
++count;
n=n&(n-1);
}
return count;
}
int main() {
printf("%d", NumberOf3(10));
return 0;
}
相关题目:
- 用一台语句判断一个整数是不是2的整数次方。
res = (n&(n-1))?false:true
- 输入两个整数m和n,计算需要改变m的二进制表示中的多少位才能得到n。
// 该问题我们可以分成两步:1、两个数进行异或操作, 2、统计二进制1的个数
#include <iostream>
#include <cmath>
using namespace std;
int numOfStep(int m, int n){
int temp=m^n;
int count=0;
while(temp) {
count++;
temp=temp&(temp-1);
}
return count;
}
int main() {
printf("%d", numOfStep(10, 13));
return 0;
}