输出一个集合的幂集(所有子集)

算法设计 专栏收录该内容
1 篇文章 0 订阅

问题描述:如一个抽象集合{1,2,3},它的所有子集包括{},{1},{2},{3},{1,2},{1,3},{2,3},{1,2,3}共2的n次方个,此问题又叫求集合的幂集。

一、递归实现

        减治法的减一的思想可以用到这个问题中来,对集合A={a1,a2,···,an},将其子集分为2组,一组为{a1,···,an-1 }的子集,一组为{an},一旦我们得到了{a1,···,an-1}的所有子集列表,将列表中的每个元素都加上an,在把它们添加到列表中,以求得所有子集。下面是生成{a1,a2,a3}的子集示例:



注意生成子集的时候是从下至上生成子集的,意思是最后生成的空集。
代码实现参考了 http://www.geeksforgeeks.org/power-set/的思路

int SIZE = 5;
void printPowerSet2(char *set, int set_size)
{
	//递归出口,当当前集合不能够在分解为下一个子集的时候输出所有集合元素
	if (set_size == 0)
	{
		printf("{");
		for (int i = 0; i < SIZE; i++)
			if (set[i] != ' ')
				printf("%c", set[i]);
		printf("}");
		printf("\n");
	}
	else
	{
		//直接递归,递归生成当前集合的所有下一个状态
		printPowerSet2(set, set_size - 1);

		//动态生成子集合存储空间,通过使用空白字符替换每个位置的方式生成当前元素个数的每个子集
		//递归的在生成子集中继续查找子集
		if (set_size > 0)
		{
			char *sub_set = (char *)malloc(sizeof(char)*set_size);
			strcpy(sub_set, set);
			sub_set[set_size - 1] = ' ';
			printPowerSet2(sub_set, set_size - 1);
		}
	}
}

二、使用位运算

        建立对于n个元素集合A={a1,a2,···,an}的所有2的n次方个子集和长度为n的所有2的n次方个位串之间的一一对应关系,如果ai属于该子集,bi=1,如果ai不属于该子集,bi=0。



思路来源: http://www.geeksforgeeks.org/power-set/

void printPowerSet(char *set, int set_size)
{
	int pow_set_size = pow(2, set_size);
	int counter, j;
	for (counter = 0; counter < pow_set_size; counter++)
	{
		for (j = 0; j < set_size; j++)
		{
			if (counter & (1 << j))
				printf("%c", set[j]);
		}
		printf("\n");
	}
}


解决该问题用了很长的时间,自己真的很菜,借鉴了许多其他人的思路,算不上自己原创,这里只是做一个总结,希望下一次遇到类似的问题能过有一些思路也好。

  • 2
    点赞
  • 0
    评论
  • 21
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

zp_diandiandidi

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值