【发布时间】:2014-09-25 18:20:01
【问题描述】:
我阅读了Hamming Weight 上的维基百科文章并注意到一些有趣的事情:
因此等价于相同长度的全零字符串中的
Hamming distance。对于最典型的情况,一串位,这是字符串中 1 的数量。在这种二进制情况下,它也称为人口计数,popcount或横向总和。[强调我的]
所以我想到了一些事情。我可以通过 XORing 计算两个字符串之间的汉明距离,然后获取结果字符串的汉明权重 (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
这应该更快,尤其是内联后。
但回到最初的问题。你能用两个字符串的异或的汉明权重来找到它们的汉明距离吗?即:
HD = HW (x xor y)
【问题讨论】:
-
你是在问两个位串的异或的汉明权重是否等于它们的汉明距离? (答案:是的,从定义中可以轻松得出结论。)或者您是否要求将这种有效方法推广到一般字符串?
-
我问的是第一个以及我的实现是否也有效。
-
有趣的是,popcnt 并不总是最快的解决方案。在 Intel Haswell 处理器上,AVX2 寄存器内查找表方法更快。这里有一个可以测试各种人口计数方法的实用程序:notabs.org/blcutil。
标签: c gcc intrinsics hamming-distance