我很难理解“if(i>> j)%2 == 1”在以下函数或任何函数中是做什么的?
def powerSet(items):
N = len(items)
for i in xrange(2**N):
combo = []
for j in xrange(N):
if (i >> j) % 2 == 1:
combo.append(items[j])
yield combo
答案 0 :(得分:5)
它检查是否设置了从结尾开始计算的二进制数j
的{{1}}位。 i
右移,所以最终的i >> j
位消失了。 j
是对奇数的熟悉检查,它以二进制形式设置最后一位。
编辑:这会产生如下的电源设置。外部循环遍历n % 2 == 1
的所有2**N
子集,每个子集表示为二进制整数。然后,内部循环通过检查这些整数的items
个最后位中的哪一个被设置来构造实际子集,使用位作为子集成员资格的指示符。
例如,假设N
。然后在某些时候,N=5
将是i
。由此,可以构建集合0b10011
。首先反转这些位,因为它们由[items[0], items[1], items[4]]
从右到左编号:
j
(尝试在内循环中打印1 1 0 0 1
items[0] items[1] (nothing) (nothing) items[4]
和i
。)
答案 1 :(得分:2)
您可以在操作过程中以二进制形式打印数字以查看其工作原理。这是i = 1234和j = 4的例子。
1234二进制
>>> '{:b}'.format(1234)
'10011010010'
向右移动4个位置会导致最右边的位(0010)掉落
>>> '{:b}'.format(1234>>4)
'1001101'
模运算除以2并给出余数
>>> '{:b}'.format((1234>>4)%2)
'1'
与&操作
>>> '{:b}'.format((1234>>4)&1)
'1'
如果你有一个数字,其中第4位(从零开始)为零,则得到零
>>> '{:b}'.format((1234+0b10000>>4)&1)
'0'
答案 2 :(得分:0)
作为larsmans已经完全解决的另一种风味,这就是我理解它的方式。
i>> j只是意味着i / pow(2,j),它在数学上意味着i / 2 ^ j [显然我们在整数空间]。设置n = i / 2 ^ j。当你有n%2 == 1时,你问n mod 2是否为1?如果是,那么n必须是奇数,否则n必须是偶数。