461. Hamming Distance(leetcode)
The Hamming distance between two integers is the number of positions at which the corresponding bits are different.
Given two integers x
and y
, calculate the Hamming distance.
Note:
0 ≤ x
, y
< 2^31.
Example:
Input: x = 1, y = 4 Output: 2 Explanation: 1 (0 0 0 1) 4 (0 1 0 0) ? ? The above arrows point to positions where the corresponding bits are different.
漢明距離
是使用在數據傳輸差錯控制編碼裏面的,漢明距離是一個概念,它表示兩個(相同長度)字對應位不同的數量,我們以d(x,y)表示兩個字x,y之間的漢明距離。對兩個字符串進行異或運算,並統計結果為1的個數,那麽這個數就是漢明距離
這道題通俗的講是兩個數的二進制之間的不同之處有幾個,即異或運算後結果中1的個數。
很容易,我們可以寫出以下代碼:
public int hammingDistance(int x, int y) {
int xor = x ^ y, count = 0;
for (int i=0;i<32;i++) count += (xor >> i) & 1;
return count;
}
對x、y兩個整數進行異或運算,得到結果xor,接下來計算xor中1的個數,即可算得漢明距離。
對xor右移,然後對該二進制數與1運算(得到最右邊的那個數字是否為1),循環直到結束。
更簡單的,基於java自帶的Integer.bitCount(int i)函數,可以用一行代碼解決問題:
public int hammingDistance(int x, int y) {
return Integer.bitCount(x ^ y);
}
我們可以來看一下bitCount函數的原理:
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 的個數 , 並且用該對應的兩位來存儲這個個數 。
如 : 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 寫成二進制數的形式就容易明白了 .
[bitCount函數原理參考http://15838341661-139-com.iteye.com/blog/1642525]
461. Hamming Distance(leetcode)