您的位置:首页 > 编程语言 > C语言/C++

C语言 生成集合的幂集

2016-04-26 02:37 375 查看
小白一枚,大神勿喷

如题,设集合A为{a,b,c},

那么集合A的幂集P(A)应为

{空集}, {a}, {b}, {c}, {a,b}, {a,c}, {b,c}, {a,b,c};

【分析】

我的思路是,先输出一个空集。

接下来,输出长度为len的子集。(1<=len<=集合元素的个数)

如上例,A={a,b,c};

先输出空集,NULL

再输出长度为1的子集 :{a}, {b}, {c}

再输出长度为2的子集 :{a,b}, {a,c}, {b,c}

再输出长度为3的子集 :{a,b,c};

关键的地方来了,如何抽取源数组A中长度为len的子集的元素呢。

即当len为2的时候,如何将{a,b}, {a,c}, {b,c} 有序保存到幂集P(A)中呢?

我们需要保存的长度为len,我们每次都从第0个元素开始抽取。设A1为P(A)中的一个元素。如A1 为 {a,b},就属于P(A)中。

即A1[0] = A[0];

方便起见,我们不防设index = 0; index 代表着,你当前要抽取元素的所在位置。

上式就为 A1[0] = A[index];

这时候,我们剩余的长度就为len-1,由集合定义得,集合中的元素都是不相同的,这就意味着,我们再进行,下一次的抽取的时候,位置为index+1;

即A1[1] = A[index+1];

为了更直观一些,我们为A1设置一个计数变量count 。count代表着,A1集合抽取到的元素数量。

上述两式,易化为

A1[count] = A[index];

A1[count + 1] = A[index + 1];

想必到了这里,读者的脑海中已经有了一个模型了,甚至说,已经想到解决问题的方案了。

我们用一个循环,从A中依次取出每个元素。

依次取出的每个元素,记为a1 (a1 = ‘a’ 或者a1 = ‘b’ 或者a1 = ‘c’)

我们将我们从集合A中取元素的位置,记为index;

下面我根据我们所要取的长度 len。继续取元素。(0

A1[count++] = A[index];
for(int i=index+1; i<strlen(A) && len>=0; i++)
{
A1[count++] = A[i];
len--;
}


问题阐述到这里,已经差不多了。

我们不如举个例子:

A = {a,b,c};
当len = 1时,通过for循环和len变量
得出 当index=0时,A1={a};
当index=1时,A2={b};
当index=2时,A3={c};

当len = 2时,
for(int index=0; index<strlen(A); index++)
{
Ai[count++] = A[index];
len--;
for(int i=index+1; i<strlen(A)&&len>=0; i++)
{
Ai[count++] = A[i];
len--;
puts(Ai);
}
}


注意我这里用的是Ai,而不是A1,那是因为,针对len=2来说,每个for循环,都产生一个独立的Ai;

以上代码结果为A1={a,b}, A2={a,c};A3={b,c};

到了这里,读者不仅又会感到疑惑了,如果我要取三个元素,岂不是要写三个循环嵌套。如果我要取N个元素,岂不是要写N个。

这是大大不必的,以上的论述,只是针对下文作铺垫。

上面的情况,我们完全可以用递归来解决。

首先,我们把问题归纳为:

从A中取出长度为len的不同元素。

即fun(A,len);

另外,我们需要加入一个index元素,来保证我们每次取的元素,都在index的位置后面,这样可以避免取到相同元素。

即fun(A,len,index);

当然,我们需要用一个循环,来保证每次的index的位置都是不同的。

for(int index=0; index<strlen(A); index++)
{
A1 = fun(A,len,index);
}


而我们的fun函数功能体,可以这么解决。

当长度len == 0时,我们输出A1,并return;

否则,我们继续如下代码

for(int i=index+1; i<strlen(A); i++)
{
fun(A,len,i);
len--;
}


我这里的代码,只是一个描述性代码,并没有具体实现任何功能。仅仅是控制递归的结束。

到这里,我想大家的思路已经都很明确了。

我的代码如下。欢迎指正!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 5

void fun(char *arr, int len, int index, char *res, int resi)
{
if(len == 0 || index >= strlen(arr) || resi == strlen(arr)-1)
{
if(res[0] != 0)
puts(res);
return ;
}
else
{
res[resi] = arr[index];
if(index == strlen(arr)-1 && len == 1)
puts(res);
for(int i=index+1; i<strlen(arr); i++)
{
if(len-1 == 0)  i=strlen(arr);
fun(arr,len-1,i,res,resi+1);
}
}
}

int main()
{
char arr[N+1] = "abcde";
puts("NULL");

for(int i=
4000
1; i<strlen(arr); i++)
{
for(int j=0; j<strlen(arr)-i+1; j++)
{
char res[N+1]={0};
fun(arr,i,j,res,0);
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 幂集