简单快速地计算二进制整数的汉明距离为0?

时间:2016-03-14 18:04:23

标签: java c++ hamming-distance binary-operators

我正在写一个数独求解器,我必须计算我学到的东西被称为int0的汉明距离,例如7(二进制为111)到0的汉明距离为3。所以我只是这样做:

for(int dist = 0 ; num != 0 ; num>>=1) dist += (num&1);

虽然效果很好,但我发现它有点笨拙。我试图想出一个二元操作技巧来计算距离(主要是为了好玩),但我只能找到适用于距离1的方法:

(num-1) ^ ((num<<1)-1) == num → true only if hamming dist to 0 == 1

我查看了StackOverflow和网络,但我找不到任何东西。

假设num 永远不为负且始终小于512,是否有更好/更优雅的方式来评估它,也许是一些二元操作技巧?如果没有,根据上面的假设,汉明距离的近似值是否始终在误差< 1内?

3 个答案:

答案 0 :(得分:2)

要创建9位的查找表(因为这是针对Sudoku):

int dist[512];
dist[0] = 0;
for (i=1; i<512; i++)
    dist[i] = (i&1) + dist[i/2];

为了避免初始计算,这也可以写为记忆递归函数。

int dist(int bits) {
    static _dist[512] = {};
    if (bits == 0)
        return 0;
    else if (_dist[bits] == 0)
        _dist[bits] = (bits & 1) + dist(bits/2);
    return _dist[bits];

答案 1 :(得分:1)

在java中,您可以使用静态方法Integer.bitCount(int i)

如果你需要用另一种语言,这就是java源码,它应该是非常好的翻译。

select row_number()over(order by dt) as id
,dt as created_at
,cnt1+cnt2+cnt3+cnt4+cnt5 as cnt
from
(
    select
    date_table.dt
    ,lag(cnt,2,0)over(order by created_at asc) as cnt1
    ,lag(cnt,1,0)over(order by created_at asc) as cnt2
    ,isnull(cnt,0) cnt3
    ,lead(cnt,1,0)over(order by created_at asc) as cnt4
    ,lead(cnt,2,0)over(order by created_at asc) as cnt5
    from
    date_table left join
    (select created_at,count(*) as cnt from your_table group by created_at) c
on date_table.day = c.created_at
) T

答案 2 :(得分:0)

不确定,如果这有帮助,但出于好奇我通过模板实现了它:

template <int N>
struct Hamming {
    enum { value = Hamming< (N/2) >::value + (N&1)};    
};
template <>
struct Hamming<0>
{
    enum { value = 0 };
};


int main() {
    std::cout << Hamming<7>::value << std::endl;
    return 0;
}

只有在编译时知道N才能使用它,因此我认为你必须在你的情况下使用其他东西。但是,它很好地演示了如何(原则上)完全避免运行时的任何计算。