要求:

  给定一个集合,枚举所有可能的子集。此处的集合是不包含重复元素的。

Method0: 增量构造法

  思路:每次选取一个元素至集合中,为了避免枚举重复的集合,此处要采用定序技巧 -- 除了第一个元素,每次选取必须要比集合中的前一个元素要大!

  

// A 为原集合;
// B 为子集,每次调用函数即会打印一次
// cur 为子集元素个数
void print_subset0(int *A, int *B, int N, int cur) {
for(int i=0; i<cur; i++) {
printf("%5d", B[i]);
}
printf("\n");
if( cur < N ) {
for( int i=0; i<N; i++ ) {
if( !cur || A[i] > B[cur-1] ) {
B[cur] = A[i];
print_subset0(A, B, N, cur+1);
}
}
}
} int main() {
int Length = 3;
int A[Length] = {1, 3, 2};
printf("Method0:\n");
int B[Length] = {0};
print_subset0(A, B, Length, 0);
printf("\n");
return 0;
}

  采用的是递归调用,但此处不需要return语句,因为当没有元素可用于枚举时,就不会调用函数,也就是不会继续递归。

   此函数输出的子集中是包含空集的,如果不想用空集,则需判断 cur 是否为0,不为0才打印子集

   测试样例的输出结果(包含空集):

    

Method1: 位向量法

  思路:1个容量为N的集合,每个位置0~N-1,对于每个子集,要么被选中,要么没被选中。枚举每一个位置的状态,可得到各种子集。

  

// A 为原集合;
// A 为原集合
// used为当前A中每个位置的元素的状态(选中或未被选中)
// cur代表现在枚举A[cur]的状态
void print_subset1(int *A, int *used, int N, int cur) {
if( cur == N ) {
for(int i=0; i<N; i++) {
if( used[i] ) {
printf("%5d", A[i]);
}
}
printf("\n");
return ;
}
used[cur] = 0;
print_subset1(A, used, N, cur+1);
used[cur] = 1;
print_subset1(A, used, N, cur+1);
} int main() {
int Length = 3;
int A[Length] = {1, 3, 2}; printf("Method1:\n");
int B[Length] = {0};
print_subset1(A, B, Length, 0);
printf("\n"); return 0;
}

  同样是递归枚举,这里需要用return终止递归,终止条件就是cur == N即枚举了一种子集,然后输出  

  此函数的输出是包含空集的,如果不想要空集,则需要判断used函数是否全为0,如果全为0,则不输出

  样例输出(包含空集):

    

Method10: 二进制法

  类似于位向量法,同样也是枚举各个位置的状态,但这次用二进制表示,二进制长度为N,与原集合大小相同。二进制的第 i 位代表原集合中的第 i 位是否被选中,枚举各种情况。集合大小为N,就是2的N次种方式。

  

void print_subset10(int *A, int N, int seq) {
for(int i=0; i<N; i++) {
if( seq & (1<<i) ) {
printf("%5d", A[i]);
}
}
printf("\n");
} int main() {
int Length = 3;
int A[Length] = {1, 3, 2};
printf("Method10:\n");
for(int i=0; i<(1<<Length); i++) {
print_subset10(A, Length, i);
}
printf("\n");
return 0;
}

  这种方式很好写,也很好记,但问题是,因为函数中的形参seq是int型的,所以N最大也就只能32,如果long long,那N也只能最大64,再超过64,就需要用大数或其它表示方式表示了。

   如果不想要空集,可以将main函数中的 i 从1枚举起。

  样例输出结果(包含空集):

    

参考资料: 《算法竞赛入门经典(第2版)》

枚举子集的3种方式 -- C++描述的更多相关文章

  1. Java Enum枚举 遍历判断 四种方式(包括 Lambda 表达式过滤)

    示例代码如下: package com.miracle.luna.lambda; import java.util.Arrays; /** * @Author Miracle Luna * @Date ...

  2. iOS中枚举定义的三种方式

    最简单的方式 typedef enum{ num1 = 0, num2 = 1, num3 = 2 }num; 同时我们还可以使用NS_ENUM的方式定义枚举 typedef NS_ENUM (NSI ...

  3. Java Array数组 遍历 四种方式(包含 Lambda 表达式遍历)

    示例代码如下: package com.miracle.luna.lambda; import java.util.Arrays; /** * @Author Miracle Luna * @Date ...

  4. Java List集合 遍历 四种方式(包含 Lambda 表达式遍历)

    示例代码如下: package com.miracle.luna.lambda; import java.util.ArrayList; import java.util.List; /** * @A ...

  5. Java Map集合 遍历 五种方式(包含 Lambda 表达式遍历)

    示例代码如下: package com.miracle.luna.lambda; import java.util.HashMap; import java.util.Iterator; import ...

  6. ASP.NET Core 四种方式绑定枚举值

    前言 本节我们来讲讲在ASP.NET Core MVC又为我们提供了哪些方便,之前我们探讨过在ASP.NET MVC中下拉框绑定方式,这节我们来再来重点看看枚举绑定的方式,充分实现你所能想到的场景,满 ...

  7. verilog描述表决器的两种方式简易分析

    命题:设计一个三变量表决器.真值表如下: 可以写出并简化得出公式:F=AB+BC+AC. 以下是两种算法: 第一种:仅从算法方面描述为:A.B.C的和大于1则输出结果为1,否则为0:源码如下: mod ...

  8. 《JS高程》创建对象的7种方式(完整版)

    一.理解对象 ECMA-262定义对象:无序属性的集合,其属性可以包含基本值.对象或者属性. 我们可以把 ECMAScript 的对象想象成 散列表:无非就是一组 名值对,其中值可以是数据或函数. 创 ...

  9. uva1354 天平难题 【位枚举子集】||【huffman树】

    题目链接:https://vjudge.net/contest/210334#problem/G 转载于:https://blog.csdn.net/todobe/article/details/54 ...

随机推荐

  1. 本地yum源安装GCC

    Linux环境下yum源安装GCC 前提条件是有Linux环境的安装盘ISO文件 在Linux系统中创建两个目录,一个是用来存放ISO文件,一个是用来挂载该ISO文件,如下: $mkdir /root ...

  2. Img垂直居中

    IMG垂直居中问题 2011-02-22 10:51:00|  分类: CSS |  标签:垂直居中  div  align  img  vertical  |举报|字号 订阅    转载来自:htt ...

  3. JavaSE复习日记 : 循环语句(for/while/do while)

    /* * 循环语句(for循环,while和do while循环) */ /* * for循环语句 * * for循环语法: * for (表达式1;表达式2;表达式3 ){ * java语句 * } ...

  4. vs2010更改默认环境设置

    今天刚刚装vs2010手欠点击了新建团队项目,在百度上各种查找说让我去 visual studio tools的命令提示中进行 devenv命令行修改 ResetString但是没找到我设置文件的路径 ...

  5. BZOJ 3931: [CQOI2015]网络吞吐量( 最短路 + 最大流 )

    最短路 + 最大流 , 没什么好说的... 因为long long WA 了两次.... ------------------------------------------------------- ...

  6. 5.6.3.8 fromCharCode()方法

    String构造函数本身还有一个静态方法:fromCharCode().这个方法的任务是接收一或多个字符编码,然后将它们转换成一个字符.从本质上来看,这个方法与实例方法charCodeAt()执行的是 ...

  7. sqlserver 在将 nvarchar 值 'XXX' 转换成数据类型 int 时失败

    最近做oracle和sqlserver数据库兼容,感觉sqlserver真心没oracle好用,存储过程竟然只能返回int类型,疯了 疯了 存储过程的output及return的区别 sql取整 ce ...

  8. codeforces 613A. Peter and Snow Blower

    题目链接 给一个多边形, 一个多边形外的定点, 求这个点距离多边形的最短距离和最长距离. 最长距离肯定是和某个顶点的连线, 而最短距离是和点的连线或是和某条边的连线. 对于一条边上的两个点a, b, ...

  9. [LeetCode]题解(python):005-Longest Palindromic Substring

    题目来源: https://leetcode.com/problems/longest-palindromic-substring/ 题意分析: 这道题目是输入一段不超过1000的字符串,输出最长的回 ...

  10. [置顶] MongoDB 分布式操作——分片操作

    MongoDB 分布式操作——分片操作 描述: 像其它分布式数据库一样,MongoDB同样支持分布式操作,且MongoDB将分布式已经集成到数据库中,其分布式体系如下图所示: 所谓的片,其实就是一个单 ...