题目说明:

给定一组数字或符号,产生所有可能的集合(包括空集合),例如给定1 2 3,则可能的集合为:{}、{1}、{1,2}、{1,2,3}、{1,3}、{2}、{2,3}、{3}。

题目解析:

如果不考虑字典顺序,则有个简单的方法可以产生所有的集合,思考二进位数字加法,并注意1出现的位置,如果每个位置都对应一个数字,则由1所对应的数字所产生的就是一个集合,例如:

000 {}
001 {3}
010 {2}
011 {2,3}
100 {1}
101 {1,3}
110 {1,2}
111 {1,2,3}

了解这个方法之后,剩下的就是如何产生二进位数?有许多方法可以使用,您可以使用unsigned型别加上&位元运算来产生;

如果是32个以内的元素集合可以采用unsigned int来储存,这样直接遍历再根据比特位显示出元素就可以了。

  1. 比如3个元素,则对应最大值是2^3 = 8;
  2.  
  3. for (int i=0; i < 8; i++)
  4. ShowResult(&i, 3); //根据bit位显示结果

这里我假定任意个元素集合求子集合,通过数组来表示任意长位数;

程序代码:

  1. #include <gtest/gtest.h>
  2. using namespace std;
  3.  
  4. void ShowResult(bool Bits[], int nSize)
  5. {
  6. cout << "{";
  7. for (int i=0; i<nSize; ++i)
  8. {
  9. if (Bits[i])
  10. {
  11. cout << i+1 << " ";
  12. }
  13. }
  14. cout << "}\n";
  15. }
  16.  
  17. bool Add(bool Bits[], int nSize)
  18. {
  19. for (int i = nSize -1; i >= 0; --i)
  20. {
  21. Bits[i] = !Bits[i]; // 如果是1变成0再进位,如果是0变成1退出。
  22. if (Bits[i])
  23. {
  24. return true;
  25. }
  26. }
  27.  
  28. return false;
  29. }
  30.  
  31. // 二进制法
  32. int GenerateSubset(int nSize)
  33. {
  34. if (nSize==0)
  35. {
  36. cout << "{}" << endl;
  37. return 1;
  38. }
  39.  
  40. int nCount = 0;
  41. bool *Bits = new bool[nSize];
  42. memset(Bits, false, sizeof(bool)*nSize);
  43.  
  44. do
  45. {
  46. ShowResult(Bits, nSize);
  47. nCount++;
  48. }
  49. while(Add(Bits, nSize));
  50.  
  51. delete[] Bits;
  52.  
  53. return nCount;
  54. }
  55.  
  56. TEST(Algo, tCombination)
  57. {
  58. // 0个数子集合数 =〉2^0 = 1
  59. ASSERT_EQ(GenerateSubset(0), 1);
  60.  
  61. // 3个数子集合数 =〉2^3 = 8
  62. ASSERT_EQ(GenerateSubset(3), 8);
  63.  
  64. // 5个数子集合数 =〉2^5 = 32
  65. ASSERT_EQ(GenerateSubset(5), 32);
  66.  
  67. // 10个数子集合数 =〉2^10 = 1024
  68. ASSERT_EQ(GenerateSubset(10), 1024);
  69. }

参考引用:

根据组合数和二项式定理

子集个数:Cn0+Cn1+Cn2+...+Cnn = (1+1)^n=2^n

  1. 看书、学习、写代码

[经典算法] 排列组合-N元素集合的所有子集(一)的更多相关文章

  1. [经典算法] 排列组合-N元素集合的所有子集(二)

    题目说明: 给定一组数字或符号,按照字典序产生所有可能的集合(包括空集合),例如给定1 2 3,则可能的集合为:{}.{1}.{1,2}.{1,2,3}.{1,3}.{2}.{2,3}.{3}. 题目 ...

  2. [经典算法] 排列组合-N元素集合的M元素子集

    题目说明: 假设有个集合拥有n个元素,任意的从集合中取出m个元素,则这m个元素所形成的可能子集有那些? 题目解析: 假设有5个元素的集合,取出3个元素的可能子集如下: {1 2 3}.{1 2 4 } ...

  3. python算法-排列组合

    排列组合 一.递归 1.自己调用自己 2.找到一个退出的条件 二.全排列:针对给定的一组数据,给出包含所有数据的排列的组合 1:1 1,2:[[1,2],[2,1]] 1,2,3:[[1,2,3],[ ...

  4. HDU5145:5145 ( NPY and girls ) (莫队算法+排列组合+逆元)

    传送门 题意 给出n个数,m次访问,每次询问[L,R]的数有多少种排列 分析 \(n,m<=30000\),我们采用莫队算法,关键在于区间如何\(O(1)\)转移,由排列组合知识得到,如果加入一 ...

  5. 递归算法之排列组合-求一个集合S的m个元素的组合和所有可能的组合情况

    求一个集合S的m个元素组合的所有情况,并打印出来,非常适合采用递归的思路进行求解.因为集合的公式,本身就是递归推导的: C(n,m) = C(n-1,m-1) + C(n-1,m). 根据该公式,每次 ...

  6. 排列组合或容斥原理 SPOJ - AMR11H

    题目链接: https://vjudge.net/contest/237052#problem/H 这里给你一串数字,让你计算同时拥有这串数字最大值和最小值的子集(连续)和子序列(可以不连续)的数量, ...

  7. PHP的排列组合问题 分别从每一个集合中取出一个元素进行组合,问有多少种组合?

    首先说明这是一个数学的排列组合问题C(m,n) = m!/(n!*(m-n)!) 比如:有集合('粉色','红色','蓝色','黑色'),('38码','39码','40码'),('大号','中号') ...

  8. N个数组中所有元素的排列组合(笛卡尔积)算法

    (1)N个数组对象中所有元素排列组合算法 private List<List<Object>> combineAlg(List<Object[]> nArray) ...

  9. 排列组合算法(PHP)

    用php实现的排列组合算法.使用递归算法,效率低,胜在简单易懂.可对付元素不多的情况. //从$input数组中取$m个数的组合算法 function comb($input, $m) { if($m ...

随机推荐

  1. js实现异步循环

    @(编程) 问题 实现异步循环时,你可能会遇到问题. 让我们试着写一个异步方法,每秒打印一次循环的索引值. for(var i = 0; i < 5; i++) { setTimeout(fun ...

  2. CCF 201312-5 I’m stuck! (暴力,BFS)

    问题描述 给定一个R行C列的地图,地图的每一个方格可能是'#', '+', '-', '|', '.', 'S', 'T'七个字符中的一个,分别表示如下意思: '#': 任何时候玩家都不能移动到此方格 ...

  3. C#与C++对应的类型

    //c++:HANDLE(void   *)       ----   c#:System.IntPtr         //c++:Byte(unsigned   char)   ----    c ...

  4. 汇编语言程序入门实验一:在dos下对用户输入作出应答

    汇编语言程序入门实验一:在dos下对用户输入作出应答 1,背景 成功预言了今天要上计算机操作系统上机实验课,昨天预习后,今天的两个上机实验做得很成功.但是也有一些问题.问题1:学校的系统目前是wind ...

  5. lbs basic mongodb

    MongoDB地理位置索引常用的有两种. db.places.ensureIndex({'coordinate':'2d'}) db.places.ensureIndex({'coordinate': ...

  6. Labeled ContentControl & LabeledControl【项目】

    LabeledTextBoxControl: C#定义 using System; using System.Collections.Generic; using System.Linq; using ...

  7. 更改VisualStudio默认创建类和接口不加public问题

    由于VisualStudio创建类和接口时,默认的是不加public关键字的,而我们大多数时候创建的类都是public的,于是,为了更好工作觉得改之. 首先找到在VisualStudio安装目录下路径 ...

  8. erlang自定义数据类型

    Erlang系统自带的基础数据类型有:atom.tuple.list.binary.pid.float.number.port.reference.record. 用户可以通过通过命令type来自定义 ...

  9. div图片垂直居中 如何使div中图片垂直居中

    (从已经死了一次又一次终于挂掉的百度空间人工抢救出来的,发表日期 2014-04-03) 『此方法在ie7下,如果.box的高度为800等比较大的数值时,并不能起到垂直居中的作用.』 点评:关于图片垂 ...

  10. Sublime Text3 激活教程

    Sublime Text3激活 在使用Sublime时会定期弹出购买提示框,避免出现购买提示,影响工作效率,我们可以使用网上的激活码,虽然有些不厚道,但是工作以后,一定选择购买正版支持一下. 打开Su ...