1. 程式人生 > >輸出一個集合的冪集(所有子集)

輸出一個集合的冪集(所有子集)

問題描述:如一個抽象集合{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}的子集示例:
注意生成子集的時候是從下至上生成子集的,意思是最後生成的空集。
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");
	}
}


解決該問題用了很長的時間,自己真的很菜,借鑑了許多其他人的思路,算不上自己原創,這裡只是做一個總結,希望下一次遇到類似的問題能過有一些思路也好。