思路一

可以用递推的思想,观察S=[], S =[1], S = [1, 2] 时解的变化。

可以发现S=[1, 2] 的解就是 把S = [1]的所有解末尾添上2,然后再并上S = [1]里面的原有解。因此可以定义vector<vector<int> > 作为返回结果res, 开始时res里什么都没有,第一步放入一个空的vecotr<int>,然后这样迭代n次,每次更新res 内容,最后返回res。

#include<iostream>
#include<vector>
using namespace std; void subset1(int *a, int n)
{
vector<vector<int>> sub(1);// (pow(2, n) + 1);
//这种初始化方式是直接插入了1个为空的元素。此时sub.size()是1。
//扩展容量用resize,提高性能
sub.reserve(pow(2, n) + 1);
for (int i = 0; i < n; ++i)
{
int len = sub.size();
for (int j = 0; j < len; ++j)
{
auto temp = sub[j];
temp.push_back(a[i]);
sub.push_back(temp);
}
}
for (int i = 0; i < sub.size(); ++i)
{
for (int j = 0; j < sub[i].size(); ++j)
{
cout << sub[i][j];
}
cout << endl;
}
}
int main()
{
int a[] = { 1,2,3,4 };
subset1(a, 4);
}

  结果   第一个空行代表空集。

1
2
12
3
13
23
123
4
14
24
124
34
134
234
1234
请按任意键继续. . .

  

思路二

所谓子集,就是包含原集合中的一些元素,不包含另一些元素。如果单独看某一个元素,它都有两种选择:"被包含在子集中"和"不被包含在子集中",对于元素个数为n、且不含重复元素的S,子集总数是2n。因此我们可以遍历S的所有元素,然后用递归考虑每一个元素包含和不包含的两种情况。

代码,这种思路需要用到递归

#include<iostream>
#include<vector>
using namespace std; static vector<vector<int>> sub2;
void subset2(int *a, int n, int t, vector<int> temp)
{
if (t == n)
{
sub2.push_back(temp);
return;
}
subset2(a, n, t + 1, temp);
temp.push_back(a[t]);
subset2(a, n, t + 1, temp);
} int main()
{
int a[] = { 1,2,3,4 };
vector<int> temp; subset2(a, 4, 0, temp);
for (int i = 0; i < sub2.size(); ++i)
{
for (int j = 0; j < sub2[i].size(); ++j)
cout << sub2[i][j];
cout << endl;
}
}

  结果  第一个空行代表空集。

4
3
34
2
24
23
234
1
14
13
134
12
124
123
1234
请按任意键继续. . .

  

思路三

用一个unsigned int 的每个bit位来表示子集的每一个元素的两种情况。前提 原集合中不含重复字符。(含有的话,会出现重复)

#include<iostream>
#include<vector>
using namespace std; static vector<vector<int>> sub2;
void subset3(int *a, int n)
{
unsigned int num = 1 << n;
cout << num << endl;
for (unsigned int i = 0; i < num; ++i)
{
unsigned int q = i;
for (int j = 0; j < n; ++j,q>>=1)
{
if (q & unsigned int ( 1))
{
cout <<a[j];
}
}
cout << endl;
}
} int main()
{
int a[] = { 1,2,3,4 };
subset3(a, 4);
}

  结果  第二个空行代表空集。

16

1
2
12
3
13
23
123
4
14
24
124
34
134
234
1234
请按任意键继续. . .

  

	vector<int> temp2 = temp;
subset2(a, n, sum, t, f + 1, temp);//当前的不包含
temp.push_back(a[f]);
subset2(a, n, sum, t +a[f], f,temp);//可重复的重点
temp2.push_back(a[f + 1]);
subset2(a, n, sum, t + a[f+1],f+1, temp2);//当前的包含

元素可重复,求子集的元素和为一个常数 

#include<iostream>
#include<vector>
#include<set>
using namespace std; static set<vector<int>> sub2;//去重
//a是数组,n数组个数,sum一开始就是0,t是要求的和,f一开始是0
void subset2(int *a, int n,int sum, int t, int f,vector<int> temp)
{
if (t > sum)
return;
if (t == sum)
{
sub2.insert(temp);
return;
}
if (f == n)return;
vector<int> temp2 = temp;
subset2(a, n, sum, t, f + 1, temp);
temp.push_back(a[f]);
subset2(a, n, sum, t +a[f], f,temp);
temp2.push_back(a[f + 1]);
subset2(a, n, sum, t + a[f+1],f+1, temp2); } int main()
{
int a[] = { 4,1,3,2};
vector<int> temp;
subset2(a, 4,7,0,0, temp);
for (auto p = sub2.begin(); p != sub2.end(); ++p)
{
for (int j = 0; j < (*p).size(); ++j)
cout << (*p)[j];
cout << endl;
}
}  

结果:和为7

1111111
111112
11113
11122
1132
1222
133
322
4111
412
43
请按任意键继续. . .

  

subset子集全排序问题的更多相关文章

  1. R语言︱排序问题

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 数据排序 1.sort(),rank(),or ...

  2. 第K大子集-LH

    题解:搜索+二分 对于每个数有选与不选两种情况.然后我们先搜前一半的状态,每个数选还是不选. 有2^17种,然后我将每种状态拍一个序先存着.然后我再搜后一半的状态,2^18种. 假设后一半某一种情况的 ...

  3. CSDN-Markdown语法集锦

    前言: 使用Markdown近一个来月.越来越认为不舒爽. 改字体.改字号.改颜色.改样式,全不会!想加个数学公式.得,仅仅会截图.把图片传上去了还不会控制大小.也不会控制文字与图片的排版,写出来的博 ...

  4. Player Settings 导出设置

    Player Settings is where you define various parameters (platform specific) for the final game that y ...

  5. 播放器设置 Player Settings

    原地址:http://game.ceeger.com/Manual/class-PlayerSettings.html#Android Player Settings is where you def ...

  6. Unity导包配置详解

    Player Settings is where you define various parameters (platform specific) for the final game that y ...

  7. words2

    餐具:coffee pot 咖啡壶coffee cup 咖啡杯paper towel 纸巾napkin 餐巾table cloth 桌布tea -pot 茶壶tea set 茶具tea tray 茶盘 ...

  8. 2019-8-31-Latex-公式速查

    title author date CreateTime categories Latex 公式速查 lindexi 2019-08-31 16:55:58 +0800 2018-05-25 16:5 ...

  9. Latex 公式速查

    本文记录了一些常用的数学公式对应的 Latex 字符,用于快速查找需要的字符 所有的在 Latex 使用的字符公式,都需要放在\(和\),$ 和 $,\begin{math} 和\end{math}之 ...

随机推荐

  1. oracle里的统计信息

    1 oracle里的统计信息 Oracle的统计信息是这样的一组数据,存储在数据字典,从多个维度描述了oracle数据库对象的详细信息,有6种类型 表的统计信息:记录数.表块的数量.平均行长度等 索引 ...

  2. 24 mysql怎么保证主备一致

    Mysql主备的基本原理 在状态1中,客户端直接访问节点A,而节点B只是备库,只是将A的binlog全部同步过来并应用到本地,这样可以保持节点B和节点A的数据是相同的. 当需要切换的时候,就变成状态2 ...

  3. 第三章 深入分析Java Web中的中文编码问题

    3.1 几种常见的编码格式 3.1.1 为什么要编码 一个字节 byte只能表示0~255个符号,要表示更多的字符,需要编码. 3.1.2 如何翻译 ASCII码:有128个,用一个字节的低7位表示. ...

  4. springboot成神之——log4j2的使用

    本文介绍如何在spring-boot中使用log4j2 说明 依赖 日志记录语句 log4j2配置文件 本文介绍如何在spring-boot中使用log4j2 说明 log4j2本身使用是非常简单的, ...

  5. List对象中的组合、查询、扩展

    var Pnts = segs.Select( c =>                                             pntTsLst.Where           ...

  6. 优化深度神经网络(二)优化算法 SGD Momentum RMSprop Adam

    Coursera吴恩达<优化深度神经网络>课程笔记(2)-- 优化算法 深度机器学习中的batch的大小 深度机器学习中的batch的大小对学习效果有何影响? 1. Mini-batch ...

  7. 【整理】Android中的gravity和layout_gravity区别

    [背景] 在Android中,想要设置个按钮的水平对齐,都累死了: [已解决]ADT中已设置TableLayout布局的情况下如何设置按钮居中对齐    所以现在有必要搞清楚,到底gravity和la ...

  8. MySQL 示例数据库sakila-db的安装

    最近在看 “高性能MySql”这本神书,发现上面很多例子采用的官方示例数据库sakila. 官方示例数据库 下载地址 http://dev.mysql.com/doc/index-other.html ...

  9. spark编译安装 spark 2.1.0 hadoop2.6.0-cdh5.7.0

    1.准备: centos 6.5 jdk 1.7 Java SE安装包下载地址:http://www.oracle.com/technetwork/java/javase/downloads/java ...

  10. JAVA基础知识总结18(反射)

    反射技术: 其实就是动态加载一个指定的类,并获取该类中的所有的内容.而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员.简单说:反射技术可以对一个类进行解剖. 反射的 ...