C++:排列組合算法


轉載請注明出處

排列組合數是一種非常實用的工具,計算出所有的排列組合可以解決一些實際的工程問題。所以,掌握計算排列組合的方法是十分必要的。

目前,網上已經有一些計算排列組合數的算法,比如http://www.cnblogs.com/shuaiwhu/archive/2012/04/27/2473788.html 。

大部分排列組合算法都是用了遞歸的思想,在這里我也給出我的一個實現方法,這個算法同樣采用了遞歸的方式,但是采用了分治的思想。

為敘述方便,我們先將問題轉化成對數組的下標進行排列組合。

比如對於數組a={'a','b','c','d','e'}.

我們只需要對數組a的下標進行排列組合,之后通過下標訪問即可,比如得到結果之一為(1,3,4),那么通過訪問數組a即可得到最終結果(‘b’,‘d’,‘e’)。

思路:

對於求排列組合C(5,3),我們可以對結果分成兩類:A類是含有下標5的結果,B類是不含下標5的結果;

同理,對於B類,我們可以將B類繼續分成兩類:B1類是含有下標4的結果(且不含下標5的結果),B2類是不含下標4的結果(且不含下標5的結果);

同理,對於B2類,我們可以繼續分成兩個子類:B21類是含有下標3的結果(且不含下標5、4的結果),B22類是不含下標3的結果(且不含下標5、4的結果);

注意,此時B22類是不成立的(應為不含下標3、4、5,只剩下下標1、2兩個元素),所以已經將所有獨立的子集找到,完成遍歷。

其中,

對於A類,我們只需要求解C(4,2),之后再在返回的結果中加入5即可;

對於B類,可以分成B1和B2兩類:

對於B1類,我們只需要求解C(3,2),之后再在返回的結果中加入4即可;

對於B2類,可以分成B21和 B22兩類:

對於B21類,我們只需要求解C(2,2),之后再在返回的結果中加入3即可;

對於B22類,不成立,結束。

可以發現,問題C(5,3)已經降維成三個小問題:C(4,2),C(3,2) 和C(2,2)。利用遞歸的方法即可實現最終結果的求解。


下面是源代碼:

/*****************************************************************************************************************************
時間復雜度:
空間復雜度:
功能:求排列組合Cij
輸入參數:
int i : 總數
int j : 組合數
vector<int>r: 用於存儲臨時結果的向量,大小必須等於num
int num : 組合數
vector<vector<int> > & result : 用於存儲最終所有結果的二維向量
返回參數:
void
注意: 
首先建立兩個向量作為函數的輸入參數
vector<int> r(num); //num為組合數
vector<vector<int> > result; //存儲最終結果
使用樣例:
vector<int> resulttemp(3);
vector<vector<int> > result;
Cij(6,3,resulttemp,3,result);
*****************************************************************************************************************************/


void Cij(int i, int j,vector<int> &r,int num,vector<vector<int> > & result)
{
//排列組合公式Cij
//cout << n << ' ' << i << ' ' << j << endl;
if (j == 1)
{
for (int k = 0; k < i; k++)
{
vector<int> temp(num);
r[num - 1] = k;
for (int i = 0; i < num;i++)
{
temp[i]=r[i];
//cout << r[i] << ' ';
}
result.push_back(temp);
//cout << endl;
}
}
else if (j == 0)
{
//do nothing!
}
else
{
for (int k = i; k >= j; k--)
{
r[j-2] = k-1;
Cij(k - 1, j - 1,r,num,result);
}
}
}

下面是測試結果:




注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com