题目:
解法一:循环和位移动
思路:遍历每一位。
public class Solution6 {
public int hammingWeight(int num){
int bit_num = 0;
int mask = 1;
for (int i=0; i<32; i++){
if ((num & mask) != 0){
bit_num += 1;
}
mask <<= 1;
}
return bit_num;
}
public static void main(String[] args){
Solution6 s = new Solution6();
int test_int = -3;
int result = s.hammingWeight(test_int);
System.out.println(result);
}
}
解法二:位操作的小技巧
思路:n和(n-1)做&位运算,可以把最后一个1变成0。
不再检查每一位,而是只关注最后一个1,不断把最后一个1反转,直到没1时结束。
public class Solution7 {
public int hammingWeight(int n){
int count;
for (count=0; n!=0; ++count){
n = n & (n-1);
}
return count;
}
public static void main(String[] args){
int test_int = -3;
Solution7 s = new Solution7();
int result = s.hammingWeight(test_int);
System.out.println(result);
}
}
附:java中的位运算符
位移操作:(只针对int类型的有效,Java中,一个int的长度始终是32位,也就是4个字节,它操作的都是该整数的二进制数).也可作用于以下类型,即 byte,short,char,long(它们都是整数形式)。当为这四种类型时,JVM先把它们转换成int型再进行操作。
1、与(&)运算符,两个都为1时才为1,其他情况均为0
2、或(|)运算符,两个都为0时才为0,其他情况均为1
3、非(~)运算符,取反,即1变为0,0变为1
4、异或(^)运算符,相同值为0,不同值为1
5、右移(>>)运算符,m>>n,把m的二进制数右移n位,m为正数,高位全部补0,m为负数,高位全部补1。
注意:在数字没有溢出的情况下:m>>n相当于m除以2的n次方,得到的数为整数时,即为结果;得到的数为小数时,根据m的有值两种情况:
1.m为正数时,得到的商会舍弃小数位
2.m为负数时,得到的商会舍弃小数位,然后把整数部分+1得到结果
例1:5>>2
5的二进制形式为:00000000 00000000 00000000 00000101
进行逻辑运算后为(右移两位):00000000 00000000 00000000 00000001
转换为十进制为:1
例2:5>>4
5的二进制形式为:00000000 00000000 00000000 00000101
进行逻辑运算后为(右移四位):00000000 00000000 00000000 00000000
转换为十进制为:0
注意:这里舍弃了小数点后面的
例3:-5>>2
-5的二进制形式为:11111111 11111111 11111111 11111011
进行逻辑运算后为(右移两位):11111111 11111111 11111111 11111110
转换为十进制为:-2
6、左移(<<)运算符,m<<n,把m的二进制数左移n位,高位超出n位都舍弃,低位补0(此时可能出现正数变负数)
注意:在数字没有溢出的情况下,对于正数和负数,m<<n相当于m乘以2的n次方。
例1:5<<2
5的二进制形式为:00000000 00000000 00000000 00000101
进行逻辑运算后为(左移两位):00000000 00000000 00000000 00010100
转换为十进制为:20
例2:5<<29
5的二进制形式为:00000000 00000000 00000000 00000101
进行逻辑运算后为(左移两位):10100000 00000000 00000000 00000000
转换为十进制为:-1610612736
7、无符号右移(>>>)运算符,m>>>n,整数m表示的二进制右移n位,不论正负数,高位都补0
例1: 5>>>2
5的二进制形式为:00000000 00000000 00000000 00000101
进行逻辑运算后为(无符号右移两位):00000000 00000000 00000000 00000001
转换为十进制为:1
例2:-5>>>2
-5的二进制形式为:11111111 11111111 11111111 11111011
进行逻辑运算后卫(无符号右移两位):00111111 11111111 11111111 11111110
转换为10进制为:1073741822