生成组合的两种方法

生成组合的两种方法

方法1:搜索

代码

#include<iostream>
using namespace std;
char S[5]={'A', 'B', 'C', 'D'};             //大小为4的集合S,0号不用
char zh[5];                                 //存放组合的数组,0号不用
int  nS=4;                                  //集合S的大小
int  cnt=0;                                 //非空集合的个数

void zuhe1(int k, int start){               //k用来控制递归的层数,不超过nS
	for(int i=start; i<=nS; i++){           //增加元素的选择范围:S[start]~S[nS]
		zh[k]=S[i];                         //添加一个元素,就构成一个组合
		cnt++;                              //计数器加1
		for(int x=1; x<=k; x++)             //输出当前组合
		    cout<<zh[x];
		cout<<endl;
		if(k<nS) zuhe3(k+1, i+1);           //k<nS时,才可以递归
	}	
}

int main(){
    zuhe1(1, 1);
    cout<<cnt;
    return 0;
}

输出结果

A                               //这样达到的是组合效果,如果不限定start位置,就成了排列
AB
ABC
ABCD
ABD
AC
ACD
AD
B
BC
BCD
BD
C
CD
D
15

方法2:搜索+回溯

代码

#include<iostream>
using namespace std;
char S[5]={' ', 'A', 'B', 'C', 'D'};                //大小为4的集合S,0号不用
char ztS[5];                                        //S每个元素的状态,有 或 没有
int  nS=4;                                          //S集合的大小
int  cnt=0;                                         //非空集合的个数

void zuhe2(int k){                                  //k用来控制递归的层数,不超过nS
	if(k==nS+1){                                    //终止条件,nS个元素的状态已明确
		cnt++;                                      //计数器加1
		for(int i=1; i<=nS; i++)                    //输出组合
			if(ztS[i])	cout<<S[i];
		cout<<endl;
		return;                                     //返回
	}
	ztS[k]=1;                                       //未达终止条件:有S[k]的组合,左子树
	zuhe2(k+1);                                     //递归
	ztS[k]=0;                                       //未达终止条件:无S[k]的组合,右子树
	zuhe2(k+1);                                     //递归
}

int main(){
	zuhe2(1);
	cout<<cnt-1;			                        //要减去一个空集 
	return 0;
}

输出结果

ABCD                                                //个数为2^4-1,为二叉树的15个叶子
ABC
ABD
AB
ACD
AC
AD
A
BCD
BC
BD
B
CD
C
D

15
posted @ 2017-06-03 22:42  LFYZOI题解  阅读(648)  评论(0编辑  收藏  举报