我在算法的源代码中发现了这个循环。我认为有关这些问题的详细信息与此无关,因为这只是解决方案的一小部分。
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) “
答案 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);
});
并进行迭代可能会让您感到清楚。