我在Hamming Weight上阅读了维基百科的文章并发现了一些有趣的内容:
因此等同于来自相同长度的全零字符串的
Hamming distance
。对于最典型的情况,一串位,这是字符串中的1的数量。在此二进制的情况下,它也称为人口数,popcount
或横向总和。[强调我的]
我发生了什么事。我可以通过 XOR
计算两个琴弦之间的汉明距离,然后取结果字符串的汉明重量(POPCOUNT)吗?
有些事情(使用gcc
内在函数):
#include <stdint.h>
int hammingDistance (uint64_t x, uint64_t y) {
uint64_t res = x ^ y;
return __builtin_popcountll (res);
}
现在,至于为什么我想要这样做,好吧,在某些平台上,是的,这只会转换为gcc
发出对计算popcount
的函数的调用。例如,在没有popcnt
的x64上,gcc
吐出(Godbolt's GCC Online):
hammingDistance:
sub rsp, 8
xor rdi, rsi
call __popcountdi2
add rsp, 8
ret
OTOH,如果你有一个支持POPCOUNT的平台,比如x64模型,包括nehalem
和之后(有POPCNT
),你得到(Godbolt's GCC Online):
hammingDistance:
xor rdi, rsi
popcnt rax, rdi
ret
应该更快,特别是一旦内联。
但回到最初的问题。你能把两个弦的XOR的汉明重量找到它们的汉明距离吗?即:
HD = HW (x xor y)
答案 0 :(得分:5)
两个相等长度的字符串x
和y
之间的汉明距离定义为它们不同的位置数。如果x
和y
是位串,x^y
是一个字符串1
s,它们的位置完全相同。因此,HammingDistance(x,y) = Number of 1s in x^y
,用于位串。此外,HammingWeight(x) = number of 1s in x
表示位串x
。因此,您的第一个声明HammingDistance(x,y) = HammingWeight(x^y)
适用于位串。确定后,很明显您的实施是正确的。
答案 1 :(得分:3)
是的,这很有效。对于每个位,当且仅当输入位不同时,该位为1。因此,应用于整个位向量,结果具有与输入具有不同位(HD)一样多的一位(HW)。而且你的代码似乎很好地利用了这种关系。事实上,这个快捷方式甚至可以进一步提到您链接到的汉明重量文章(Efficient implementation):
两个单词A和B的汉明距离可以计算为A xor B的汉明重量。