很多时候,我们需要求一个集合子集,对于求子集,对于集合元素要么存在于子集中,要么不存在,
因此可以抽象用1位二进制数来表示,当该值为0,表示这个元素不在该集合中,反之则存在。
比如{a,b,c,d}, 求该集合子集,可以退化成4位二进制数_ _ _ _的排列问题, 总共排列2*2*2*2=16.
位操作1<<1=0b10, 1<<2=0b100,1<<3=0b1000,1<<4=0b10000=16,为所有子集个数,
因此若一个集合有n个元素,则子集个数为1<<n个,生成所有子集代码如下:
void bo()
{
for(int i = 0; i < 1<<(size); i++)
{
for(int j = 0; j < size;j++)
{
sa[i][j] = i&(1<<j)&&1; //
cout<<sa[i][j]<<" ";
}
cout<<endl;
}
}
下面是一个利用位操作,求子集的例子:
#include <iostream>
using namespace std;
#define MAX 100
int size = 0;
int sa[MAX*MAX][MAX]={0};
char ca[MAX];
void genca();
void bo();
void subset();
int main(void)
{
cout<<"size:";
cin>>size;
genca();
bo();
subset();
return 0;
}
void bo()
{
for(int i = 0; i < 1<<(size); i++)
{
for(int j = 0; j < size;j++)
{
sa[i][j] = i&(1<<j)&&1;
cout<<sa[i][j]<<" ";
}
cout<<endl;
}
}
void genca()
{
for(int i=0;i<size;i++)
ca[i]='a'+i;
}
void subset()
{
for(int i=0;i<1<<size;i++)
{
for(int j=0;j<size;j++)
if(sa[i][j])
cout<<ca[j]<< " ";
cout<<endl;
}
}
输出的结果如下:
./bo
size:3
0 0 0
1 0 0
0 1 0
1 1 0
0 0 1
1 0 1
0 1 1
1 1 1
a
b
a b
c
a c
b c
a b c