• variable-precision SWAR算法:计算Hamming Weight


    variable-precision SWAR算法:计算Hamming Weight

    转自我的Github

    最近看书看到了一个计算Hamming Weight的算法,觉得挺巧妙的,纪录一下。

    Hamming Weight,即汉明重量,指的是一个位数组中非0二进制位的数量。

    对于这个问题,最直观的算法就是遍历二进制位,时间复杂度是O(n),每次需要遍历n个位。另外一个算法是查表,用一个数组记录下一定位数每个数值的汉明重量如:数组hwTable=[0, 1, 1, 2]纪录了0, 1, 2, 3的汉明重量。这个算法的时间复杂度也是O(n),但是不需要执行n次,而是只需要执行n/m次,m取决于查表一次能够决定的二进制位的长短,这个算法需要使用额外的空间为O(m^2)。

    而我们接下来的所提到的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
    }

    计算32位的位数组只需要O(1),而且比查表法需要的空间更少。

    乍一看好像看不出什么头绪,只要动手一步步之行一下这个算法就可以看到它的巧妙之处。下面我们一步步执行一下这个算法:

    5: 0101    3: 0011    F:    1111
    input:    0011 1010 0111 0000 1111 0010 0001 1011
    step1:    0001 0000 0101 0000 0101 0000 0001 0001(i&0x55555555)
               0001 0101 0001 0000 0101 0001 0000 0101((i>>1)&0x55555555)
               0010 0101 0110 0000 1010 0001 0001 0110(+)
    
    step2:    0010 0001 0010 0000 0010 0001 0001 0010(i&0x33333333)
            0000 0001 0001 0000 0010 0000 0000 0001((i>>2)&33333333)
            0010 0010 0011 0000 0100 0001 0001 0011(+)
    
    step3:    0000 0010 0000 0000 0000 0001 0000 0011(i&0x0F0F0F0F)
            0000 0010 0000 0011 0000 0100 0000 0001((i>>4)&0x0F0F0F0F)
            0000 0100 0000 0011 0000 0101 0000 0100(+)
    
    step4: ...


    可以清楚的看到,第一步的结果中,每两位为一组,纪录了这两位里面非0位的个数;第二步的执行结果中,每四位为一组,纪录了每四位里面非0位的个数;第三步的结果中,每八位为一组,纪录了每八位里面非0位的个数;第四步只要想想笔算乘法就清楚了^_^。当然如果一次要计算六四位也是可以的。。

    这个是目前已知效率最好的计算汉明重量的通用算法,在redis的bit array中也有使用,不过redis中将SWAR算法和查表法结合起来了。

  • 相关阅读:
    (转)Java中金钱的类的计算
    (转)如何实现删除重复记录并且只保留一条?
    MAXIMO-IBM文件夹的笔记
    maximo功能修改笔记
    maximo功能修改(初步理解)
    如何将两张表查询的结果集和下一张表查询
    Birt 折腾一周总结
    一天天的sql总结
    maximo弹框设置新的功能测试总结
    关于对 maximio平台的五个常用类的初步理解及总结
  • 原文地址:https://www.cnblogs.com/katsura/p/5686138.html
Copyright © 2020-2023  润新知