集合的所有分割方式---2013年1月28日

简介:
     问题描述:分割集合成多个子集合,这几个子集合间没有交集且他们的并集是原集合。
       思路:将包含n个元素的集合set的分割表示为n个数字。比如set[]={1,2,3,4},那么{1,2},{3,4}就可以表示为1122,这4个数分别表示set[0]在第一个分割集合,set[1]在第一个分割集合,set[2]在第二个分割集合,set[3]在第二个分割集合。将这个过程称为编码。
       然后抓住两个要点:
       1.第i个元素的编码一定小于或者等于i。约定一下,set原集合已经从小到大排列好,分割的集合也是这样排好。然后,很容易理解,第1个元素的编码肯定为1。接着,第2个元素如果在第一个分割集合中,那么他的编码也是1;但如果不是在第一个分割集合中,那么第2个元素的编码肯定是2,因为在第二个分割集合中,最小的数最少也是2;依次类推,可以很容易用数学归纳法证明。
       2.第i个元素的编码一定小于等于1,2,3,....i-1这些元素的编码中的最大值再加1。这也很容易想到,也很容易用数学归纳法证明。
       抓住这个要点后,就用深度搜索构造一颗子集合树就可以解决问题了。但是,我在构造子集树的过程中出现了一个思维上的错误,导致浪费了不少调试的时间。具体的错误见代码注释的描述。
       代码如下:
 1 #include <stdio.h>
 2 #define MAX 1000
 3 
 4 int set[MAX]={1,2,3,4};
 5 int n=4;
 6 int code[MAX]={1,1,1,1};
 7 
 8 //prototype
 9 void DFS(int index);
10 
11 void print_set()
12 {
13     int index;
14     int max=-1;
15     printf("{");
16     for(index=0;index<n;index++)
17     {
18         if(code[index]==1) 
19             printf("%d ",set[index]);
20         if(max<code[index])
21             max=code[index];
22     }
23     printf("},{");
24     for(index=2;index<=max;index++)
25     {
26         int index_2; 
27         for(index_2=0;index_2<n;index_2++)
28             if(code[index_2]==index)
29                 printf("%d ",set[index_2]);
30         printf("},{");
31     }
32     printf("\n");
33 }
34 
35 //find out the max code of 1,2,3...i-1 and plus 1
36 int max_pre(int i)
37 {
38     int index;
39     int max=-1;
40     for(index=0;index<i;index++)
41         if(code[index]>max)
42             max=code[index];
43     return (max+1); 
44 }
45 
46 int main()
47 {
48     int i; 
49     DFS(1);
50     return 0;
51 }
52 
53 void DFS(int index)
54 {
55     print_set();
56     if(index==n)
57         return ;
58     for(;index<n;index++)
59     {  
60         int temp=code[index]+1;
61         //在写这里的代码时,我出现了一个思维上的误区:在回溯时我只顾把code[index]++,而没有将code[index]在2到max_pre(index)遍历,这导致了我调试了挺长时间。
62         for(;temp<=index+1 && temp<=max_pre(index);temp++)
63         {
64             int save=code[index];
65             code[index]=temp;
66             DFS(index+1);
67             code[index]=save;
68         }
69 
70     }
71 
72 }
本文转自NeilHappy 51CTO博客,原文链接:http://blog.51cto.com/neilhappy/1127670,如需转载请自行联系原作者
相关文章
|
6天前
如何实现数组和 List 之间的转换?
如何实现数组和 List 之间的转换?
|
4天前
13.从M个球中取出N个球的所有组合情况
13.从M个球中取出N个球的所有组合情况
8 0
|
6天前
|
容器
06-数据容器(序列列表-元组-字符串)的切片操作
06-数据容器(序列列表-元组-字符串)的切片操作
|
6天前
|
存储 SQL C#
C# 读取二维数组集合输出到Word预设表格
C# 读取二维数组集合输出到Word预设表格
|
6天前
|
存储 自然语言处理
QT案例词典 -- 存储内容及遍历
QT案例词典 -- 存储内容及遍历
14 1
|
6天前
|
存储
C#-集合小例子
C#-集合小例子
30 0
|
5月前
三大集合---Set集合 超详细易懂,加案例分析
三大集合---Set集合 超详细易懂,加案例分析
|
7月前
|
索引 Python
python之列表元素的访问,修改,组合以及判断和截取。
python之列表元素的访问,修改,组合以及判断和截取。
|
10月前
|
JSON JavaScript 数据格式
查找一组数据中一组或多组数据(filter和find的区别)
查找一组数据中一组或多组数据(filter和find的区别)
59 0