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 >> ) & 0x55555555);
i = (i & 0x33333333) + ((i >> ) & 0x33333333);
i = (i & 0x0F0F0F0F) + ((i >> ) & 0x0F0F0F0F);
i = (i * (0x01010101) >> );
return i
}

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

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

:     :     F:
input:
step1: (i&0x55555555)
((i>>)&0x55555555)
(+) step2: (i&0x33333333)
((i>>)&)
(+) step3: (i&0x0F0F0F0F)
((i>>)&0x0F0F0F0F)
(+) step4: ...

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

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

variable-precision SWAR算法:计算Hamming Weight的更多相关文章

  1. variable precision SWAR算法

    计算二进制形式中1的数量这种问题,在各种刷题网站上比较常见,以往都是选择最笨的遍历方法“蒙混”过关.在了解Redis的过程中接触到了variable precision SWAR算法(以下简称VP-S ...

  2. variable-precision SWAR算法介绍

    BITCOUNT命令是统计一个位数组中非0进制位的数量,数学上称作:”Hanmming Weight“ 目前效率最好的为variable-precision SWAR算法,可以常数时间内计算出多个字节 ...

  3. Hamming Weight的算法分析(转载)

    看代码时遇到一个求32bit二进制数中1的个数的问题,感觉算法很奇妙,特记录学习心得于此,备忘. 计算一个64bit二进制数中1的个数. 解决这个问题的算法不难,很自然就可以想到,但是要给出问题的最优 ...

  4. 统计无符号整数二进制中1的个数(Hamming weight)

    1.问题来源 之所以来记录这个问题的解法,是因为在在线编程中经常遇到,比如编程之美和京东的校招笔试以及很多其他公司都累此不疲的出这个考题.看似简单的问题,背后却隐藏着很多精妙的解法.查找网上资料,才知 ...

  5. [算法]从一道题引出variable-precision SWAR算法

    苏君君出了一道题,是牛客网上面的: 输入一个int型整数,输出该数二进制表示中1的个数.其中负数用补码表示. 其实这道题并不难,大家很容易想到的解法是转成字符串的思路,即如下所示: public st ...

  6. Fp关联规则算法计算置信度及MapReduce实现思路

    说明:參考Mahout FP算法相关相关源代码. 算法project能够在FP关联规则计算置信度下载:(仅仅是单机版的实现,并没有MapReduce的代码) 使用FP关联规则算法计算置信度基于以下的思 ...

  7. Canopy算法计算聚类的簇数

    Kmeans算是是聚类中的经典算法.步骤例如以下: 选择K个点作为初始质心 repeat 将每一个点指派到近期的质心,形成K个簇 又一次计算每一个簇的质心 until 簇不发生变化或达到最大迭代次数 ...

  8. 分类模型的F1-score、Precision和Recall 计算过程

    分类模型的F1分值.Precision和Recall 计算过程 引入 通常,我们在评价classifier的性能时使用的是accuracy 考虑在多类分类的背景下 accuracy = (分类正确的样 ...

  9. 利用CORDIC算法计算三角函数

    这里主要先介绍如何利用CORDIC算法计算固定角度\(\phi\)的\(cos(\phi)\).\(sin(\phi)\)值.参考了这两篇文章[1].[2]. 一般利用MATLAB计算三角函数时,用\ ...

随机推荐

  1. 2016-11-15NOIP模拟赛

    AM学军OJ T1 暴力 #include<bits/stdc++.h> using namespace std; typedef long long LL; + ; int len, p ...

  2. 来试试这个来自静态代码分析工具PVS Studio提供C++的小测验吧

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:来试试这个来自静态代码分析工具PVS Studio提供C++的小测验吧.

  3. ABAP多表关联查询

    inner join(等值连接) 只返回两个表中联结字段相等的行 left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有 ...

  4. dublin core实例

    <?xml version="1.0"?> <metadata xmlns="http://example.org/myapp/" xmlns ...

  5. cocos2d-x 2.0 拖尾效果分析

    转自:http://game.dapps.net/gamedev/game-engine/7281.html 在Cocos2d-x中,拖尾效果有一个专门的类CCMotionStreak来实现.下面我们 ...

  6. Android AsyncTask运作原理和源码分析

    自10年大量看源码后,很少看了,抽时间把最新的源码看看! public abstract class AsyncTask<Params, Progress, Result> {     p ...

  7. creating normals from alpha/heightmap inside a shader

    http://www.polycount.com/forum/showthread.php?t=117185 I am making some custom terrain shaders with ...

  8. keepalived + haproxy 实现web 双主模型的高可用负载均衡--转

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://xz159065974.blog.51cto.com/8618592/140581 ...

  9. Java基础知识强化之集合框架笔记71:模拟斗地主洗牌和发牌并对牌进行排序的案例

    1. 模拟斗地主洗牌和发牌并对牌进行排序的原理图解: 2. 代码实现: 思路: • 创建一个HashMap集合 • 创建一个ArrayList集合 • 创建花色数组和点数数组 • 从0开始往HashM ...

  10. 全球5大安全工具Linux发行版本

    全球5大安全工具Linux发行版本http://automationqa.com/forum.php?mod=viewthread&tid=2314&fromuid=21