【排列组合】子集生成

题目描述:

给定一个集合,枚举它所有可能的子集。

这道题的主流算法有三种,本文介绍最难的——二进制法(讲解在代码中)

#include<iostream>
#include<string>
#include<list>
#include<algorithm>
using namespace std;

list<list<int> > getSubstr(string A, int n){
	
	list<list<int> > res;//用来存储结果 
	
	//从全1,也就是全选开始,每次减1,正好取完所有的子集
	for(int i = (1<<n)-1; i > 0; i--){ //(1<<n)-1为2的n次方减一,正好对应n位全1的二进制数
		list<int> s;
		for(int j = n-1; j >= 0; j--){ //表示i右移j位,查看没位的二进制数,从而判断数组的该位是否取 
			if((i>>j)&1 == 1) s.push_back(A[j] - '0');//每一个小的集合对应一位数,每j个小几个push到大集合中形成一组解
		}
		res.push_back(s);
	}
	return res;
}

int main(){
	string s;
	cin >> s;
	list<list<int> > res = getSubstr(s,s.length());
	//遍历输出
	for(list<list<int> >::iterator it = res.begin(); it != res.end(); it++){
		//由于C++不像Java,每一个迭代器拿出来的都没法直接当作一个对象,所以这里需要定义一个临时集合
		list<int> rs = *it;
		for(list<int>::iterator it1 = rs.begin(); it1 != rs.end(); it1++){
			cout << *it1;
		}
		cout << " ";
	}
	cout<<endl;
	
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为梦而生~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值