面向特定子集的位操作:枚举子集时变量t所代表子集的技术问询
关于内层循环变量
t对应的子集解释 嘿,这个问题我太熟了,当初刚学位操作子集枚举的时候也琢磨了好久!咱们一步一步拆明白:
首先明确前置条件:
- 外层循环的
state是所有包含第0个元素(对应二进制最低位,也就是state & 1 != 0)的非空子集——外层for枚举了n个元素的所有非空子集,再通过if (state & 1)筛选出必须包含第一个元素(索引0)的那些子集。
然后看内层循环的核心操作:t &= t - 1。这个操作的魔法在于,它会立刻清除t二进制表示中最右边的那个1。比如t是0b1011(对应子集{0,1,3}),t-1就是0b1010,按位与之后得到0b1010(去掉了最右边的1,也就是对应元素0的位);再一次t-1是0b1001,按位与得到0b1000(又去掉了最右边的1,对应元素1的位);直到t变成0,循环结束。
那内层循环里的每个t,对应的就是原state子集的一系列“递减”子集:从完整的state子集开始,每次去掉当前子集最右边的那个元素(也就是二进制里最右边的1对应的元素),直到只剩下原state中最左边的那个元素(最高位的1)为止。
举个具体的例子,假设n=4,state=0b1101(对应子集{0,2,3},满足state&1 !=0):
- 第一次
t=0b1101→ 对应子集{0,2,3} - 第二次
t=0b1101 & 0b1100 = 0b1100→ 去掉最右边的1(元素0),对应子集{2,3} - 第三次
t=0b1100 & 0b1011 = 0b1000→ 去掉最右边的1(元素2),对应子集{3} - 第四次
t=0b1000 & 0b0111 = 0→ 循环结束
总结一下:内层循环的t依次代表包含第0个元素的原state子集,以及该子集去掉最右侧元素后的所有非空子集(直到只剩原state最高位元素的子集)。或者更精准的说法是:所有由state中若干个高位的1组成的非空子集(包括完整的state本身),每个子集都是通过逐步移除state最右侧的1得到的。
内容的提问来源于stack exchange,提问作者amont
相关产品推荐
相关产品推荐

