C++求字符集合的所有子集(幂集)

本文介绍了如何使用C++编写递归函数来生成给定n个元素集合的所有子集(包括2^n个),并展示了如何构建和传递结果集,以求解幂集问题。
摘要由CSDN通过智能技术生成
/*
设计递归函数,用来输出n个元素的所有子集(2^n个)。
      考题:由一个集合的所有子集构成的集合称为该集合的________。(幂集)
思路:设n个元素(a1,...an)构成的集合为Sn,如果已经有了Sn中前n-1个元素(a1,a2,...an_1,其集合记作Sn_1)的子集An_1,则
      所求结果为①An_1并上以下集合:将an放入An_1的各个元素(也是集合)中构成新的元素(也是集合)所组成的集合②。
	  如
	    Sn={b,c,a},
	  则①An_1={{},{b},{c},{b,c}},
	      an=a,
	    ②    ={{a},{a,b},{a,c},{a,b,c}}
	  则An = ①∪② ={{},{b},{c},{b,c},{a},{a,b},{a,c},{a,b,c}}即为最终结果。
	 可以用递归或非递归两种方式求解。这里按要求用递归来求解。
	 难点:如何构建输出(结果集)且能在函数间传递?-> vector和全局变量result
*/
#include <iostream>
#include <vector>
using std::cout;
using std::cin;
using std::endl;
using std::vector;

typedef vector<char> subset;                 //存放{a,b}这样的子集
vector<subset> result = {subset() };         //上述子集的集合,形如{{},{a,b},{a}},用于保存每一步处理的结果。最后就是总的结果。

void solve(vector<char>& src)
{
	if (src.size())
	{
		//删除来源中的末尾字符
		char c = src.back();                 //保存末尾元素,后面会用到
		src.pop_back();
		solve(src);				             //删除末尾元素后的集合再次求解更小规模的问题(减少一个字符):
		//至此,得到了前n-1次处理的结果
		vector<subset> temp = result;		 //前n-1个元素构成的所有子集的集合,拷贝一份
		for (auto it = temp.begin(); it != temp.end(); it++)
		{
			(*it).push_back(c);              //修改temp的元素,往每个子集中都添加一个c,
		}
		//循环完成后,temp中的每个元素都是含有c的字符的子集
		//然后,将temp加到result后面,构成新的result。
		result.insert(result.end(), temp.begin(), temp.end());		
	}
	else {						             // src中没有字符了
		return;
	}
}
//打印字符集中字符的一种组合(一个字符子集,如{'a','b','c'})
void print_combination(const subset& s)
{
	cout << "{";
	for (auto it = s.begin(); it != s.end(); it++)
		cout << *it ; 
	cout << "}";
}
//打印所有子集,需调用print_combination函数
void print_subsets(const vector<subset>& r)
{
	int i = 0;
	cout << "{"<<endl;
	for (auto it = r.begin(); it != r.end(); it++)
	{
		cout << ++i << ":";
		print_combination(*it);
		cout << "\n";
	}
	cout << "}"<<endl;
}

//主函数
int main()
{
	char s[] = { 'A','B','C'};								   //初始字符集:可用动态数组,从键盘输入值
	subset original(s,s+sizeof(s)/sizeof(char));			   //初始字符集	
	solve(original);										   //求解
	print_subsets(result);									   //打印结果
	return 0;
}

运行结果:

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值