含有n个不重复元素的集合:
- 有个子集(每个元素都有在子集中和不在子集中两种可能,共有2*2*...*2(n个2)= 种可能)
- 有个真子集(去掉该集合本身)
- 有个非空子集(去掉空集)
- 有个非空真子集(去掉空集和该集合本身)。
用二进制表示子集的方法:从右往左第i位表示元素i是否在集合中,1表示在集合中,0表示不在集合中。
例如,集合S = {1,2,3,4,5,6,7,8}的一个子集{1,3,4,8}用二进制法表示为:10001101。
二进制数 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | |
位 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
集合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;
}