题目:
已知集合A{a,b,c,d,e,f},要求列举出此集合的所有非空真子集。
分析:
因为集合有无序性,所以要列举所有的非空真子集其实就是一个组合问题。从中找出1个元素的组合,然后是2个的,再然后是3个的,知道N-1个的,第N个就是他自己了,是子集但不是真子集,所以不用算,所以需要我们列举的有2^N - 2个集合。
思路:
我是这样想的,建立一个数组,记录元素的位置,这样不管元素是什么字符,我们只用管位置这个数字就行了,先从第一个元素开始,到达指定长度则打印出这一组位置的组合,即A集合的一个子集,之后开始位置从第二个再开始,依次循环递归下去,直到最后长度和集合A的长度相同。
实现:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *A = "abcdef"; //集合元素
int eCount = 0; //存储集合中的元素个数
int * sortArr = NULL; //存储元素排列的数组
/**********************************
*函 数:void opt(int length) *
*参 数:元素长度 *
*功 能:输出一个指定长度的元素 *
*返 回:无 *
***********************************/
void opt(int length)
{
int loop = 0;
//循环输出一个真子集中的集合元素
for(;loop < length; loop++)
{
printf("%c", A[sortArr[loop]]);
}
puts(""); //换行,方便观察
}
/*********************************************************
*函 数:void trvl(int length, int nowlength, int site) *
*参 数:集合长度,当前长度,当前位置 *
*功 能:递归组合集合中指定长度的真子集 *
*返 回:无 *
**********************************************************/
void trvl(int length, int nowlength, int site)
{
//判断当前长度是否到达指定集合长度(到达的话,就不再向下执行)
if(nowlength == length)
{
opt(length); //输出此次递归的集合元素
return; //结束此次调用
}
//循环递归到当前位置到达集合的最后一个元素的位置
while(site != eCount)
{
sortArr[nowlength] = site; //记录当前位置
trvl(length, nowlength + 1, ++site); //继续递归产生下一个位置
}
}
/**********************
*函 数:int main() *
*参 数:无 *
*功 能:主函数 *
*返 回:执行结果 *
**********************/
int main()
{
int loop = 1;
eCount = strlen(A); //计算集合元素个数
sortArr = (int *)malloc(sizeof(int) * eCount); //生成存储元素排列的数组
if(sortArr == NULL)
{
puts("not have enough memory.");
exit(-1);
}
//循环遍历指定长度的子集
for(;loop < eCount; loop++)
{
trvl(loop, 0, 0); //递归遍历子集
}
free(sortArr); //释放掉申请存储元素排列的数组的内存空间
return 0;
}
结果:
a
b
c
d
e
f
ab
ac
ad
ae
af
bc
bd
be
bf
cd
ce
cf
de
df
ef
abc
abd
abe
abf
acd
ace
acf
ade
adf
aef
bcd
bce
bcf
bde
bdf
bef
cde
cdf
cef
def
abcd
abce
abcf
abde
abdf
abef
acde
acdf
acef
adef
bcde
bcdf
bcef
bdef
cdef
abcde
abcdf
abcef
abdef
acdef
bcdef
总结:
这个用递归的思路很简单,但想起来具体怎么递归的就有点乱了,虽然只有不到10行的东西。当然大家如果有更简单的方法,希望你告诉我。
本文介绍如何使用C语言实现列举给定集合(如A{a,b,c,d,e,f})的所有非空真子集。通过分析组合问题,采用递归方法,从1个元素开始直至N-1个元素,生成2^N - 2个子集。代码实现简洁,最终展示完整的子集列表。"
104660909,9086920,LeetCode994: 腐烂橘子的最小扩散时间,"['算法', 'LeetCode', '数据结构', '广度优先搜索', '网格问题']
2566

被折叠的 条评论
为什么被折叠?



