鳥泉學長告訴我的,今天想到了就順便記上。
設S表示一個01狀態集,那么它的所有非空子集x可以通過以下代碼枚舉。
for (int x = S; x; x = (x-1)&S)
簡單說明下原理(證明以后補上?):
x = (x-1)&S實際上是把S中的0全部忽略,並不斷減1的結果,比如S=1011,則x分別為:1011, 1010, 1001, 1000, 0011, 0010, 0001。忽略S中第二位的0其實就是111, 110, 101, 100, 011, 010, 001。
稱S中的1所在位為有效位,0所在位為無效位,則x中的無效位必為0,有效位為0或1,比如S=1011,x=1001(有效位加下划線)。-1就是加上-1補碼1111…,可以想成把無效位的1先加上去,比如x=1001變成1101,再加有效位的1。由於無效位加完肯定是1,會把有效位的進位“傳遞”下去,然后再位與S使得無效位變成0,實際就相當於有效位加上1111…,也就是有效位-1。