集合 —— 子集

【概述】

在集合论中,子集是一个较常用的概念,当给出一个集合 {0,1,2,...,n-1} 时,常需要生成所有的子集。

生成子集有三种方法:增量构造法、位向量法、二进制法

其中,二进制法除了可以生成子集,还是一种集合的表示方法。

【子集生成算法】

1.增量构造法

每次选出一个元素放到集合中,然后打印当前集合,由于集合 A 中的元素不确定,因此每次递归调用都要输出当前集合,这样一来,递归的边界也不需要显示的确定,当无法继续添加元素时,即停止递归

int A[N];
void subset(int cur,int n){
    for(int i=0;i<cur;i++)//打印当前集合
        printf("%d ",A[i]);
    printf("\n");
    int num=cur?A[cur-1]+1:0;//确认当前元素最小可能值
    for(int i=num;i<n;i++){
        A[cur]=i;
        subset(cur+1,n);
    }
}
int main(){
    int n;
    scanf("%d",&n);
    subset(0,n);
    return 0;
}

2.位向量法

位向量法是通过构造一个位向量 B[i],然后构建解答树,当 B[i]=1 时,说明 i 在子集 A 中

int B[N];
void subset(int cur,int n){
    if(cur==n){
        for(int i=0;i<cur;i++)//打印当前集合
            if(B[i])
                printf("%d ",i);
        printf("\n");
        return;
    }
    B[cur]=true;//选取当前元素
    subset(cur+1,n);
    B[cur]=false;//不选取当前元素
    subset(cur+1,n);
}
int main(){
    int n;
    scanf("%d",&n);
    subset(0,n);
    return 0;
}

3.二进制法

二进制法除了用于生成集合子集外,还是一种集合的表示方法。

对于集合 {0,1,2,...,n-1} 的子集,利用二进制来表示:以 1、0 的取值来表示从右向左第 i 位表示元素 i 是否在集合中,因此,可用 STL 中的 bitset<N> 来表示一个从 0~N-1 的集合,关于 bitset:点击这里

由于二进制位运算的特点,当两个子集 A、B 逐位进行位运算 A&B、A|B、A^B 时,分别对应两个集合的交集、并集、对称差集

此外,当全为 0 时,表示空集;当全为 1 时,表示全集,即 allBits=(1<<n)-1,那么,对于集合 A 的补集为:allBits^A

void subset(int cur,int n){
    for(int i=0;i<n;i++)
        if(cur&(1<<i))
            printf("%d ",i);
    printf("\n");
}
int main(){
    int n;
    scanf("%d",&n);
    for(int i=0;i<(1<<n);i++)
        subset(i,n);
    return 0;
}

【例题】

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值