Hamming Weight
即汉明重量,指的是一个位数组中非0二进制位的数量。
比如a[] = {1,0,1,0,0,1,1,0}统计非0数目为4。
比较常规的方法,按位统计,算法复杂度O(n)。
redis里实现用到了两种算法:
1 查表法 比如
0000 0001 : 1
0110 0001 : 3
……
1111 1111 : 8
SWAR算法
代码:
// 计算32位二进制的汉明重量
int32_t swar(int32_t i)
{
i = (i & 0x55555555) + ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
i = (i & 0x0F0F0F0F) + ((i >> 4) & 0x0F0F0F0F);
i = (i * (0x01010101) >> 24);
return i
}
第一步:
计算出来的值i的二进制可以按每2个二进制位为一组进行分组,各组的十进制表示的就是该组的汉明重量。
第二步:
计算出来的值i的二进制可以按每4个二进制位为一组进行分组,各组的十进制表示的就是该组的汉明重量。
第三步:
计算出来的值i的二进制可以按每8个二进制位为一组进行分组,各组的十进制表示的就是该组的汉明重量。
第四步:
i * (0x01010101)计算出汉明重量并记录在二进制的高八位,>>24语句则通过右移运算,将汉明重量移到最低八位,最后二进制对应的的十进制数就是汉明重量。
算法时间复杂度是O(1)的。