for循环中使用的位操作

时间:2016-03-28 22:47:47

标签: c++ algorithm for-loop bit-manipulation

我在算法的源代码中发现了这个循环。我认为有关这些问题的详细信息与此无关,因为这只是解决方案的一小部分。

    void update(int i, int value, int array[], int n) {
        for(; i < n; i += ~i & (i + 1)) {
            array[i] += value;
        }
}

我真的不明白for循环中会发生什么,这是一种诡计吗?我找到了类似Fenwick树的东西,但它们看起来与我在这里有点不同。

这个循环意味着什么?

另外,发现了这个:

“Bit Hack#9。隔离最右边的0位。

y = ~x&amp; (X + 1) “

3 个答案:

答案 0 :(得分:4)

你是对的:bit-hack ~i & (i + 1)应该计算为一个整数,它都是二进制0,除了对应最右边的零位{{1}的整数},设置为二进制i

因此,在1循环的每次传递结束时,它会将此值添加到自身。由于for中的相应位为零,因此具有设置它的效果,而不会影响i中的任何其他位。这将严格增加每次传递i的值,直到i溢出(或变为i,如果您从-1开始)。在上下文中,您可能希望使用i<0调用它,并设置i>=0在索引离开i < n之前终止循环。

整个函数应该具有从最小到最重要的array的原始值的零位迭代,逐个设置它们,并递增{{的相应元素的效果。 1}}。

Fenwick树是一种有效积累和查询统计数据的聪明方法;正如你所说,他们的更新循环看起来有点像这样,并且通常使用类似的bit-hack。必须有多种方法来实现这种小小的功能,因此您的源代码肯定可能正在更新Fenwick树或类似的东西。

答案 1 :(得分:2)

假设从右到左,你有一些1位,0位,然后是x中的更多位。

如果添加x + 1,则右侧的所有1都将更改为0,0将更改为1,其余部分将保持不变。例如xxxx011 + 1 = xxxx100。

在~x中,您具有相同数量的0位,1位,以及其他位的反转。按位并产生0位,一位为1位,由于其余位为和否定,因此这些位为0.

所以~x&amp;的结果(x + 1)是一个1位的数字,其中x的最右边是零位。

如果将其添加到x,则将最右边的0更改为1.因此,如果重复执行此操作,则将x中的0位从右向左更改为1。

答案 2 :(得分:1)

i函数迭代并设置value的0位从最左边的零到最右边的零,并将i添加到array元素for 1}}。

i循环检查n是否小于~i & (i + 1),如果是,array[i] += value将是一个包含所有二进制0的整数,除了最右边的位(即1)。然后value添加i来迭代自己。

8设置为$(document).ready(function(e) { $.ajaxSetup({cache:false}); setInterval(function() {$('#chatlogs').load('logs.php'); }, 1000); setTimeout(function(){ updateScroll(); }, 1190); }); 并进行迭代可能会让您感到清楚。