LeetCode 461
题目:定义Hamming distance是两个整数的二进制形式中,对应位置不同的个数。
题解:利用C/C++语言的二进制异或操作。x^y的结果是x与y的异或,异或结果的1的个数就是hamming distance。获取一个数的最低位:让这个数和1 进行&操作,都会得到这个数的最低位。每次判断完最低位后,异或结果右移一位。
class Solution {
public:
int hammingDistance(int x, int y) {
int hamdist=0,i;
i=x^y;
while(i)
{
if(i&1) hamdist++; //每次判断最低位是否为1
i=i>>1;
}
return hamdist;
}
};
c/C++二进制运算符
PS:Discussion中的有一解法,java直接return Integer.bitCount(x ^ y);该Integer.bitCount方法实现代码如下:
/**
* Returns the number of one-bits in the two's complement binary
* representation of the specified <tt>int</tt> value. This function is
* sometimes referred to as the <i>population count</i>.
*
* @return the number of one-bits in the two's complement binary
* representation of the specified <tt>int</tt> value.
* @since 1.5
*/
public static int bitCount(int i) {
// HD, Figure 5-2
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
代码解释(求二进制数中1的个数):二分法,两两一组相加,之后四个四个一组相加,接着八个八个,最后就得到各位之和了。
第一行是计算每两位中的 1 的个数 , 并且用该对应的两位来存储这个个数 ,
如 : 01101100 -> 01011000 , 即先把前者每两位分段 01 10 11 00 , 分别有 1 1 2 0 个 1, 用两位二进制数表示为 01 01 10 00, 合起来为 01011000.
第二行是计算每四位中的 1 的个数 , 并且用该对应的四位来存储这个个数 .
如 : 01101100 经过第一行计算后得 01011000 , 然后把 01011000 每四位分段成 0101 1000 , 段内移位相加 : 前段 01+01 =10 , 后段 10+00=10, 分别用四位二进制数表示为 0010 0010, 合起来为 00100010 .
下面的各行以此类推 , 分别计算每 8 位 ,16 位 ,32 位中的 1 的个数 .
将 0x55555555, 0x33333333, 0x0f0f0f0f 写成二进制数的形式就容易明白了