生成集合的所有组合 - 递归法

题目描述

输入一个集合,需要生成该集合所能得出的所有组合。举例说明:若输入集合为{1,2} , 需要生成的组合有{1},{1, 2},{2} 。该题目与生成集合的全排列有很多相似之处,同样也是一个很经典的问题。
 
 
解决思路
 
 这里我们利用递归的思想来实现该问题的解。
 
面对这样一个问题,我们需要仔细分析。题目要求生成一个集合的所有组合,也就是需要生成集合里的元素所能够组成的所有组合。于是一个很明显的思路就是要遍历该集合。一提到遍历集合,可以使用循环或者递归来实现。针对本问题,利用递归的思想是很方便的。
 
假设我们的集合为{1,2,3} ,我们从头扫描集合的元素,第一个元素为1。对于这个元素,我们可以把他放到组合集中,然后在剩下的集合里再去选择;也可以不把他放到组合集中,在剩下的集合里去选择元素放到组合集中。一般化的,假设我们的集合有n个元素,要求m个元素的组合。我们扫描每一个元素,针对该元素,我们可以将其放到组合集中,然后在剩下的n-1个元素中再选择m-1个元素;我们也可以不放该元素进集合,而直接从剩下的n-1个元素中选择m个元素。这已经是非常清晰的递归的思想了,具体代码如下。
 
 
代码
 
void combination(char *src,int num, vector<char>& result)  
{  
    if(num==0)  
    {  
        vector<char>::iterator iter=result.begin();  
        for(;iter<result.end();iter++)  
        {  
            printf("%c",*iter);  
        }  
        printf("\n");  
        return;  
    }  
    if(*src=='\0') return;  
    result.push_back(*src);  
    combination(src+1,num-1,result);  
    result.pop_back();  
    combination(src+1,num,result);  
}  
  
void all_sub_set(char *src)  
{  
    assert(src);  
    if(!src) return;  
    int i=0;  
    int len=strlen(src);  
    vector<char> result;  
  
    for(i=1;i<=len;i++)  
    {  
        combination(src,i,result);  
    }  
}  

 

小结
递归生成集合的所有组合,是考验一个程序员基本功的问题,有一些技巧性。本问题与Gray Code按序生成集合子集属于同一个问题的不同实现方法,都是很经典的解题方法。

posted on 2013-10-14 23:20  daniel+  阅读(1617)  评论(0编辑  收藏  举报

导航