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

来源:互联网 发布:阿里云ecs 1m带宽 编辑:程序博客网 时间:2024/05/22 13:14
问题描述:产生可能的集合
说明
给定一组数字或符号,产生所有可能的集合(包括空集合),例如给定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 20int 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置为0if (i == n){//如果全部为1,则查找结束,退出循环break;}else{//将找到的第一个0置为1digit[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;}



原创粉丝点击