- 论坛徽章:
- 0
|
我也贴个题目,效率要高
[quote]原帖由 "forest077"]虽然没有仔细研究,但是可以不用循环,真是N啊。两个算法都N精妙,PFPF。[/quote 发表:
forest 兄, 我来深究一下。
方法1:
很妙。 实际上方法 1 在循环中的每一步,即 b &= b-1 的作用是去掉最右面的一个1,n 记数一次。到 b 变为 0 的时候,n 就记住了有多少个 1。循环的次数是 b中含1的个数,即返回值了。在多数情况下,比用移位的方法快多了。
方法2:
更妙:该方法采用的是并行计算的方式。
a = b - ((b >;>;1 ) & m1);
从左到右, 每两位为一组,进行上述操作后,每组的二进制值为操作前含1的个数。实际上,上述操作对每个组,无外乎:
xy = 00, 01, 10, 11
进行了如下操作:
xy - ((xy>;>;1) & 01)
得到相应的:
00, 01, 01, 10
正好是00, 01, 10, 11中1的个数。
然后? 然后把这些个数加起来就完了,加的时候尽量用并行的方式,相对简单,我就不说了,请看代码。
在b含1的个数很少的时候,方法1比2要快,但多数情况下,方法2快。因为采用了并行的方法,所以方法2在b的位数越大的时候,优势也越大。
至于我说的查表,那是头脑简单的方法,实际效果应该比1好,比2差,但对64位(long long, 假64)来讲, 差不了太多。我没有仔细对比过。
就说这么多了。
哦, stonemason, 你的这两个方法是那里找到的啊?可以提供连接或更多资料吗,win_hate 不胜感谢! |
|