组合算法问题
//轉載自: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;
}
總結
- 上一篇: 边缘检测中非极大值抑制简单解释
- 下一篇: 统计学第一章--最小二乘拟合正弦函数,正