题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
思路分析
- 第一种思路:
二进制表示和1与运算,结果为1,说明最右边位置为1;右移判断各个位置是否为1- 缺点:如果是负数的情况下,符号位是1,左边补得一直为1,这样最终数字会变成0xFFFFFFFF,从而陷入死循环
- 第二种思路:二进制表示不变,让1不断左移,相与,来判断二进制表示的各个位置是否为1
- 缺点:如果数字为32位,那么要循环32次1的左移,和1的与操作。
- 第三种思路:n的二进制表示-1=把n的二进制表示最右边的一个1变为0,最右边为1的位记为m,那么m右边的全部变为1(右边的结构被破坏,所以我们要从右向左计数),m左边的数字保持不变。 循环终止条件:两个数相与变为0.
代码
public int NumberOf1(int n) {
int count=0;
while(n!=0){
count++;
n=n&(n-1);//最右边的1先计算进去,然后得到他前边的结构继续进行运算
}
return count;
}
题目2:一条语句判断一个数是不是2的整数次幂
- 二进制表示中如果只有1位为1,那么就是2的整数次幂;
- 让一个数和他的n-1相与,如果结果为0,就说明只有一位为1.
- return n&(n-1)==0
题目3:输入两个数m和n,判断m的二进制表示要经过几次改变才能变为n
- 第一步:m和n求异或得到一个结果(结果中有几个1,说明有几位不同)(异或等于1说明不相同)
- 第二步:统计异或结果中有几个1
public static int getNumberOf1(int n,int m) {
n=n^m;
return NumberOf1(n);
}
public static int NumberOf1(int n) {
int count=0;
while(n!=0) {
count++;
n=n&(n-1);
}
return count;
}