要求:

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

Method0: 增量构造法

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

  

  1. // A 为原集合;
  2. // B 为子集,每次调用函数即会打印一次
  3. // cur 为子集元素个数
  4. void print_subset0(int *A, int *B, int N, int cur) {
  5. for(int i=0; i<cur; i++) {
  6. printf("%5d", B[i]);
  7. }
  8. printf("\n");
  9. if( cur < N ) {
  10. for( int i=0; i<N; i++ ) {
  11. if( !cur || A[i] > B[cur-1] ) {
  12. B[cur] = A[i];
  13. print_subset0(A, B, N, cur+1);
  14. }
  15. }
  16. }
  17. }
  18.  
  19. int main() {
  20. int Length = 3;
  21. int A[Length] = {1, 3, 2};
  22. printf("Method0:\n");
  23. int B[Length] = {0};
  24. print_subset0(A, B, Length, 0);
  25. printf("\n");
  26. return 0;
  27. }

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

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

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

    

Method1: 位向量法

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

  

  1. // A 为原集合;
  2. // A 为原集合
  3. // used为当前A中每个位置的元素的状态(选中或未被选中)
  4. // cur代表现在枚举A[cur]的状态
  5. void print_subset1(int *A, int *used, int N, int cur) {
  6. if( cur == N ) {
  7. for(int i=0; i<N; i++) {
  8. if( used[i] ) {
  9. printf("%5d", A[i]);
  10. }
  11. }
  12. printf("\n");
  13. return ;
  14. }
  15. used[cur] = 0;
  16. print_subset1(A, used, N, cur+1);
  17. used[cur] = 1;
  18. print_subset1(A, used, N, cur+1);
  19. }
  20.  
  21. int main() {
  22. int Length = 3;
  23. int A[Length] = {1, 3, 2};
  24.  
  25. printf("Method1:\n");
  26. int B[Length] = {0};
  27. print_subset1(A, B, Length, 0);
  28. printf("\n");
  29.  
  30. return 0;
  31. }

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

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

  样例输出(包含空集):

    

Method10: 二进制法

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

  

  1. void print_subset10(int *A, int N, int seq) {
  2. for(int i=0; i<N; i++) {
  3. if( seq & (1<<i) ) {
  4. printf("%5d", A[i]);
  5. }
  6. }
  7. printf("\n");
  8. }
  9.  
  10. int main() {
  11. int Length = 3;
  12. int A[Length] = {1, 3, 2};
  13. printf("Method10:\n");
  14. for(int i=0; i<(1<<Length); i++) {
  15. print_subset10(A, Length, i);
  16. }
  17. printf("\n");
  18. return 0;
  19. }

  这种方式很好写,也很好记,但问题是,因为函数中的形参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. 1.语言概述-JavaScript权威指南笔记

    上周三的时候交给老板目前的项目第一个迭代回顾会的总结.原本是以综述性的表述方式写的,交给他之后表示程序员不要长篇大论.总结要分为优点缺点期望等等块,每块列出条目,简明扼要的表达出来.这里也用这种风格. ...

  2. c#软件工程师笔试题

    近来有打算重新找工作,还没提离职,投了几家公司简历,其中一家比较中意的公司给发了面试题,其实,好像是好几天前的事了,主要是Gmail邮箱很少用,所以一直都没去看,今天看到题目给解了. 题目如下: 题目 ...

  3. 如何在内存中压缩并加密ZIP

    项目中遇到了一个问题,考虑到安全原因,需要将文件以二进制数据的方式打包成压缩文件,并且这个压缩文件是有密码的. 去Google上找了些API,下载来看了下,琢磨出了以下方法 首先放API: <! ...

  4. 2045不容易系列之(3)—— LELE的RPG难题

    Problem Description人称“AC女之杀手”的超级偶像LELE最近忽然玩起了深沉,这可急坏了众多“Cole”(LELE的粉丝,即”可乐”),经过多方打探,某资深Cole终于知道了原因,原 ...

  5. BZOJ 3223: Tyvj 1729 文艺平衡树(splay)

    速度居然进前十了...第八... splay, 区间翻转,用一个类似线段树的lazy标记表示是否翻转 ------------------------------------------------- ...

  6. RAC ORA-12170 ora-12535/tns-12535

    现象:开发人员抱怨RAC数据库出现了时连得上时连不上的情况,用SQLPLUS一试,果然有这样的情况: SQL> conn system/*******@bjyd 已连接. SQL> con ...

  7. 5.4.2 RegExp实例方法

    RegExp对象的主要方法是exec(),该方法是专门为辅助组而设计的.exec()接受一个参数,即要应用模式的字符串,然后返回包含第一个匹配项信息的数组:或者在没有匹配项的情况下返回null.返回的 ...

  8. windows下fitness python版本安装测试

    FitNesse介绍¶ FitNesse是一套软件开发协作工具. 伟大的软件需要协作和交流,FitNesse可以帮助大家加强软件开发过程中的协作.能够让客户.测试人员和开发人员了解软件要做成什么样,自 ...

  9. 上架app被拒原因总结

    1. Terms and conditions(法律与条款) 1.1 As a developer of applications for the App Store you are bound by ...

  10. nexus REST API /artifact/maven/[resolve|redirect] returns unexpected for v=LATEST

    Novice nexus oss (2.0.0) user here – getting unexpected results when requesting v=LATEST artifact fr ...