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
问题阐述到这里,已经差不多了。
我们不如举个例子:
注意我这里用的是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的位置都是不同的。
而我们的fun函数功能体,可以这么解决。
当长度len == 0时,我们输出A1,并return;
否则,我们继续如下代码
我这里的代码,只是一个描述性代码,并没有具体实现任何功能。仅仅是控制递归的结束。
到这里,我想大家的思路已经都很明确了。
我的代码如下。欢迎指正!
如题,设集合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 语言程序(二)
- 如何写好 C main 函数
- Lua和C语言的交互详解
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解
- C语言编程中统计输入的行数以及单词个数的方法
- C语言自动生成enum值和名字映射代码
- 使用C语言判断英文字符大小写的方法
- c语言实现的带通配符匹配算法
- C语言实现顺序表基本操作汇总
- C语言中计算正弦的相关函数总结
- 使用C语言详解霍夫曼树数据结构
- C语言实现选择排序、冒泡排序和快速排序的代码示例
- 探讨C语言的那些小秘密之断言
- C语言实现BMP转换JPG的方法
- 深入探讨C语言中局部变量与全局变量在内存中的存放位置