列出所有的子集

算法要求

编写一个程序,列出{1,2,3,…,n}这个集合的所有子集,包括空集合。

列出一个集合的所有子集有很多做法,题目中并没有要求依某个特定的次序来排列, 因此是不难做出来的。

因为集合中一共有n个元素,所以总共就会有2^n子集;例如{1,2,3}有如下子集:

{}

{1} {2} {3}

{1,2} {1,3} {2,3}

{1,2,3}

分析

看到2^n,就想起了二进制数,可以使用二进制的第 i 位表示是否包含集合的第 i 个元素,如数字6的二进制形式是110,表示取集合的第2,3两个元素组成的子集。这样0~2^n -1的数字就可以表示全部子集,每一个数字代表一个子集,实现应该不难。

算法实现

#include  <stdio.h>
#include  <stdlib.h>

#define   MAXSIZE   20
#define   LOOP       1

int main(void)
{
	char digit[MAXSIZE];
	int  i, j;
	int  n;
	char line[100];

	printf("\nDirect Generation of All Subsets of a Set");
	printf("\n=========================================");
	printf("\n\nNumber of Elements in the Given Set --> ");
	gets(line);
	n = atoi(line);/*把字符串转换成整型数据*/

	/* ---You'd better check to see if n is too large--- */

	for (i = 0; i < n; i++)  /* clear all digits to 0,可以认为是初始化,注意digit是字符数组 */
		digit[i] = '0';

	printf("\n{}");          /* outpout empty set {} ,空集是所有集合的子集   */
	while (LOOP) {
		for (i = 0; i < n && digit[i] == '1'; digit[i] = '0', i++)
			;              /* find first 0 position  找到第一次出现0的位置,或者设置它为0  */
		if (i == n)         /* if none, all pos. are 1  */
			break;         /* thus all elem. are in set,这是在遍历完所有的元素之后,结束循环*/
		else
			digit[i] = '1';/* now add one to this pos,设置该位置的元素为1  */

		for (i = 0; i < n && digit[i] == '0'; i++)
			;              /* find first 1 position 找到第一次出现1的位置   */
		printf("\n{%d", i + 1);  /* show its numner and   */
		for (j = i + 1; j < n; j++) /* others,遍历后面的元素,找到标记为1的位置,打印出来该位置对应的数*/
			if (digit[j] == '1')
				printf(",%d", j + 1);
		printf("}");
	}
	return 0;
}

实验结果

当输入n=2的情况下,编译运行subset.c,实验结果如下:

213224_FP8A_2392809.png

转载于:https://my.oschina.net/donngchao/blog/630603

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值