子集生成

一:增量构造法

思路是一次选出一个元素放入集合中
#include<stdio.h>

void print_subset(int n,int a[],int cur)
{
	for (int i = 0; i < cur; i++)
		printf("%d ", a[i]);
	printf("\n");
	int s = cur? a[cur - 1] + 1 : 0;//cur为0则s为0,否则s=a[cur-1]+1,s为当前元素中最小值
	for (int i = s; i < n; i++)//a中本身已经定序,所以不会重复输出
	{
		a[cur] = i;
		print_subset(n, a, cur + 1);//递归构造子集
	}
}

int main()
{
	int a[50];
	print_subset(5, a, 0);
	return 0;
}

二:位向量法

思路是构造一个位向量b[i],用0和1标示元素,从而控制输出,通过递归达到输出所有结果的目的
#include<stdio.h>

void print_subset(int n,int b[],int cur)
{
	if (cur == n)
	{
		for (int i = 0; i < n; i++)
			if (b[i])
				printf("%d ", i);
		printf("\n");
		return;
	}
	b[cur] = 1;		 //选第cur个元素
	print_subset(n, b, cur + 1);
	b[cur] = 0;		 //不选第cur个元素
	print_subset(n, b, cur + 1);
}

int main()
{
	int a[50];
	print_subset(5, a, 0);
	return 0;
}

三:二进制法

用二进制表示子集s,s从n个0到n个1,第i个位置位置为1表面包含i
#include<stdio.h>

void print_subset(int n)
{
	for (int s = 0; s < (1 << n); s++)//s范围为[0,2^n-1],写成二进制就是n位,从n个0到n个1
	{
		for (int i = 0; i < n; i++)
			if (s&(1 << i))  //这里就是s中第i位为1的意思,也就是子集中包含i
				printf("%d ", i);
		printf("\n");
	}
}

int main()
{
	print_subset(5);
	return 0;
}





posted @ 2016-03-09 19:05  seasonal  阅读(92)  评论(0编辑  收藏  举报