AgOH

使用位运算枚举二进制子集的巧妙方法

字数统计: 193阅读时长: 1 min
2022/09/18

今天发现了一个使用位运算枚举二进制子集的风骚方法,特记录一下:

枚举子集

\(s\) 为要被枚举的集合:

1
2
for(int i=s;i;i=(i-1)&s)
cout<<bitset<4>(i)<<endl;

\(s=7=(111)_2\) 时,上述代码的运行结果为:

1
2
3
4
5
6
7
0111
0110
0101
0100
0011
0010
0001

枚举出的结果是递减的。

枚举固定大小的子集

\(n\) 为集合大小,\(m\) 为要枚举的子集大小:

1
2
for(int i=(1<<m)-1,x,y;i<(1<<n);x=i&-i,y=i+x,i=((i&~y)/x>>1)|y)
cout<<bitset<4>(i)<<endl;

\(n=4,m=2\) 时,上述代码的运行结果为:

1
2
3
4
5
6
0011
0101
0110
1001
1010
1100

枚举出的结果是递增的。

评语

太 TM 骚了……

CATALOG
  1. 1. 枚举子集
  2. 2. 枚举固定大小的子集
  3. 3. 评语