我正在阅读这本书programming pearls by Jon Bentley
,我遇到了这个问题。
给定一个非常长的序列(比如数十亿或数万亿)字节,你如何有效地计算一位的总数? (即序列中打开了多少位)
我见过的大多数解决方案都不会被认为是有效的。您认为如何有效解决这个问题?
答案 0 :(得分:4)
获取一个具有popc16
指令的CPU(计算16字节大存储区中的一位; popc表示填充计数)并在展开的循环中调用该指令。
如果仍然太慢,请将数据拆分为多个块并在独立的计算机上处理它们。在拆分或合并数据时,请注意不要产生瓶颈。
如果您绑定到C,请检查您的编译器是否提供__builtin_popc
函数。
如果不允许,请阅读“Hacker's Delight”一书。
答案 1 :(得分:1)
继Roland的回答之后,一个有效的方法来获得无符号(或一次4个字节)的1的数量是下面的逐位黑客攻击(我认为这是来自黑客的喜悦或者有点笨拙的黑客攻击)< / p>
int getn1s (unsigned x)
{
x = x - ((x >> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x + (x >> 4)) & 0x0F0F0F0F;
x = x + (x << 8);
x = x + (x << 16);
return x >> 24;
}
如果内联并在展开的循环中调用,那么结果应该提供一种相当有效的方法来计算1的字节数,就像你拥有的那样多。