下面是我在某个地方找到的算法(忘记了确切的位置,可能来自这个答案)来计算整数中设置的位数,即它的汉明权重。
function hamming_weight($i)
{
$i = $i - (($i >> 1) & 0x55555555);
$i = ($i & 0x33333333) + (($i >> 2) & 0x33333333);
return ((($i + ($i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
}
(我碰巧在 PHP 中很方便,但这实际上可以是任何语言。)
如果我没记错的话,它在 O(1) 中运行——毕竟没有分支。
现在这是我自己编写的一个位计数函数,除了可读性之外,我认为它较差:
function hamming_weight_2($i)
{
$weight = 0;
for ($k = 1, $s = 0; $k < 0xFFFFFFFF; $k *= 2, $s++)
{
$weight += (($i & $k) >> $s);
}
return $weight;
}
但是,它在哪些方面是劣质的?起初我认为“有一个循环,所以它应该在线性时间内运行”,但后来我意识到循环根本不依赖于输入的大小。无论 $i 的大小如何,迭代次数都保持不变。
因此,我想知道的是:
- 这两个算法真的可以说都在 O(1) 中运行吗?
- 如果是这样,是否有区分两者的措施?似乎第一个在某种程度上应该更好。