每日一算法:产生可能的集合(一)

问题描述:产生可能的集合
说明
给定一组数字或符号,产生所有可能的集合(包括空集合),例如给定1 2 3,
则可能的集合为:{}、{1}、{1,2}、{1,2,3}、{1,3}、{2}、{2,3}、{3}。


解法
如果不考虑字典顺序,则有个简单的方法可以产生所有的集合,思考二进位数字加法,
并注意1出现的位置,如果每个位置都对应一个数字,则由1所对应的数字所产生的就是一个集合,例如: 
000 {} 
001 {3} 
010 {2} 
011 {2,3} 
100 {1} 
101 {1,3} 
110 {1,2} 
111 {1,2,3} 
了解这个方法之后,剩下的就是如何产生二进位数?有许多方法可以使用,
您可以使用unsigned型别加上&位元运算来产生,这边则是使用阵列搜寻,
首先阵列内容全为0,找第一个1,在还没找到之前将走访过的内容变为0,
而第一个找到的0则变为 1,如此重复直到所有的阵列元素都变为1为止,

例如:000 => 100 => 010 => 110 => 001 => 101 => 011 => 111


#include <stdio.h>

#define MAXSIZE 20

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

	printf("输入集合个数:");
	scanf("%d",&n);
	for (i=0; i<n; i++)
	{
		digit[i] = '0';
	}

	printf("{}");//输出空集

	while (1)
	{
		for (i=0; i<n && digit[i] == '1'; digit[i] = '0', i++);//找到第一个0,并将前面的1置为0
		if (i == n)
		{//如果全部为1,则查找结束,退出循环
			break;
		}
		else
		{//将找到的第一个0置为1
			digit[i] = '1';
		}

		for (i=0; i<n && digit[i] == '0'; i++);//这一句貌似没用吧,i的值已经到了第一个1的位置啊???
		printf("\n{%d",i+1);//打印
		for (j=i+1; j<n; j++)
		{//如果后面也有值为‘1’的位置,也打印
			if (digit[j] == '1')
			{
				printf(",%d",j+1);
			}
		}
		printf("}");
	}
	printf("\n");
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值