排列组合 C++实现

参考文章:
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 许可协议。转载请注明出处!
感谢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值