组合算法问题

//转载自:http://blog.csdn.net/ywjun0919/article/details/11180685
// 和 http://www.2cto.com/kf/201301/181305.html
/*
题目要求:
写一个程序,打印出以下的序列。
(a),(b),(c),(d),(e)........(z)
(a,b),(a,c),(a,d),(a,e)......(a,z),(b,c),(b,d).....(b,z),(c,d).....(y,z)
(a,b,c),(a,b,d)....(a,b,z),(a,c,d)....(x,y,z)
....
(a,b,c,d,.....x,y,z)

解决思路:
 
这里我们利用递归的思想来实现该问题的解。 
面对这样一个问题,我们需要仔细分析。题目要求生成一个集合的所有组合,
也就是需要生成集合里的元素所能够组成的所有组合。于是一个很明显的思路就是要遍历该集合。
一提到遍历集合,可以使用循环或者递归来实现。针对本问题,利用递归的思想是很方便的。 
假设我们的集合为{1,2,3} ,我们从头扫描集合的元素,第一个元素为1。对于这个元素,
我们可以把他放到组合集中,然后在剩下的集合里再去选择;也可以不把他放到组合集中,
在剩下的集合里去选择元素放到组合集中。一般化的,假设我们的集合有n个元素,要求m个元素的组合。
我们扫描每一个元素,针对该元素,我们可以将其放到组合集中,然后在剩下的n-1个元素中再选择m-1个元素;
我们也可以不放该元素进集合,而直接从剩下的n-1个元素中选择m个元素。
这已经是非常清晰的递归的思想了,具体代码如下。

*/
#include<iostream>
#include<vector>
#include<string>  
#include<iterator>  
using namespace std;
using std::iterator;
void CombineRescure(vector<char> &str,vector<char>::iterator pStr,vector<char> &result,int count);
void Combine(vector<char> str,int n)
{
	if(str.empty())
		return;
	vector<char> result;
	CombineRescure(str,str.begin(),result,n);
}
/*
参数解释:
	str 表示所有元素的集合
	result 表示要输出组合集的一部分
	count 表示将要往result里添加的元素的个数
	pStr 表示往result里添加元素在str里的起始位置
*/
void CombineRescure(vector<char> &str,vector<char>::iterator pStr,vector<char> &result,int count)
{
	if(count==0){
		cout<<"(";
		//copy(result.begin(),result.end(),ostream_iterator<char,char>(cout,","));
		for(int i=0;i<result.size();i++){
			cout<<result[i];
			if(i!=result.size()-1)	cout<<",";
		}
		cout<<"),";
		return;
	}else if(pStr!=str.end()){
		result.push_back(*pStr);
		CombineRescure(str,pStr+1,result,count-1);
		result.erase(result.end()-1);
		CombineRescure(str,pStr+1,result,count);
	}
}
//-------------------------------------------------------------------------
int main()
{
	vector<char> str;
	for(int i=0;i<4;i++)
	{
		str.push_back('a'+i);
	}

	for(int i=1;i<=str.size();i++)
	{
		Combine(str,i);
		cout<<endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值