【算法】二进制法生成子集

含有n个不重复元素的集合:

  • 2^{n}个子集(每个元素都有在子集中和不在子集中两种可能,共有2*2*...*2(n个2)= 2^{n}种可能)
  • 2^{n}-1个真子集(去掉该集合本身)
  • 2^{n}-1个非空子集(去掉空集)
  • 2^{n}-2个非空真子集(去掉空集和该集合本身)。

用二进制表示子集的方法:从右往左第i位表示元素i是否在集合中,1表示在集合中,0表示不在集合中。

例如,集合S = {1,2,3,4,5,6,7,8}的一个子集{1,3,4,8}用二进制法表示为:10001101。

二进制数10001101
87654321

集合S = {1,2,3,4}的子集为:

通过判断从右往左第i个二进制位是1还是0就可知i是否在子集中。

输出S = {1,2,3,4}的所有子集:

#define n 4 // 集合中元素的个数

#include <stdio.h>
#include <math.h>

int main()
{
	for (int i = 0; i < pow(2, n); i++)
	{
		for (int j = 0; j < n; j++)
		{
			if (i >> j & 1)
			{
				printf("%d ", j + 1);
			}
		}
		printf("\n");
	}
	return 0;
}

输出S={1,2,3,4}的元素个数为2子集:

元素个数为2,即有2个二进制位为1,其余为0。

#define n 4 // 集合中元素的个数
#define m 2 // 子集中元素的个数

#include <stdio.h>
#include <math.h>

// 统计二进制位1的个数
int bit1(int num)
{
	int count = 0;
	while (num)
	{
		count++;
		num = num & (num - 1);
	}
	return count;
}

int main()
{
	for (int i = 0; i < pow(2, n); i++)
	{
		if (bit1(i) == m) // 如果i的二进制位1的个数==m,则输出子集
		{
			for (int j = 0; j < n; j++)
			{
				if (i >> j & 1)
				{
					printf("%d ", j + 1);
				}
			}
			printf("\n");
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值