参考文章:
1.https://blog.csdn.net/deepmindman/article/details/52264007
2.https://liam.page/2016/01/31/binomial-in-cpp/
排列
从n个数中,有顺序地选择m个。A(n,m)
例如,A(3,2)=6. 所有的组合分别是{1,2},{1,3},{2,3},{2,1},{3,1},{3,2}
A(n,m)=n!/[m!]
组合
从n个数中,无顺序地选择m个。C(n,m)
例如,C(3,2)=3. 所有的组合分别是{1,2},{1,3},{2,3}.
C(n,m)=n!/[m!*(n-m!)]
思路1:分治思想,递归实现。
/*****************************************************************************************************************************
时间复杂度:
空间复杂度:
功能:求排列组合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);
}
}
}
思路2:将所有元素设置标志位,被选的元素标为1,没被选的标为0。
选择过程:C(n,k)。k个1的二进制位不断向后移动。
binomial.cc
using namespace std;
vector<string>& combination
(vector<string>& res, const size_t& choose, const size_t& from);
bool compare (const char& lhs, const char& rhs);
int main () {
vector<string> res;
const size_t choose = 3, from = 5;
combination (res, choose, from);
for (size_t i = 0; i != res.size(); ++i) {
cout << res[i] << '\t';
for (size_t j = 0; j != from; ++j) {
if (res[i][j] == '1') {
cout << j + 1 << ' ';
}
}
cout << endl;
}
return 0;
}
vector<string>& combination
(vector<string>& res, const size_t& choose, const size_t& from) {
string wk = string (choose, '1') + string (from - choose, '0');
res.push_back (wk);
size_t found = string::npos;
while ((found = wk.find("10")) != string::npos) {
// 1. swap found
wk[found] ^= wk[found + 1];
wk[found + 1] ^= wk[found];
wk[found] ^= wk[found + 1];
// 2. sort before
sort (wk.begin(), wk.begin() + found, compare);
res.push_back (wk);
}
return res;
}
bool compare (const char& lhs, const char& rhs) {
return lhs > rhs;
}
参考文章:
作者: Liam Huang
原文链接: https://liam.page/2014/09/28/review-of-the-continent/
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
感谢