转载请注明出处

1 介绍

排列(Permutation)和组合(Combination)是两个基础的数学概念。

计算排列与组合可以解决一些实际的工程问题,掌握排列组合计算的方法是十分重要的。

目前,网上已经有一些计算排列组合的算法,比如[1]。

这里我也给出一个组合计算方法。该计算方法采用了分治的思想,代码实现采用了递归的方式。

2 组合算法

2.1 设计思路

组合问题:在序列An={1,2,3,4,5,6,...,n}中选择m个数一共有C(n,m)种组合,求解所有的组合。

例如,C(3,2)=3. 所有的组合分别是{1,2},{1,3},{2,3}。

思路:

我的算法采用了分治的思想:将一个大的问题拆分成很多个子问题,先解决子问题,所有子问题的解共同组成了大问题的解。

接下来我以求组合C(5,3)为例进行说明:

假设C(5,3)的所有组合形成的集合是E。我们可以将组合结果E分成两类:A类是含有5的组合,B类是不含5的组合;

同理,我们可以将B类分成B1和B2两类:B1类是含有4的组合(且不含5的组合),B2类是不含4的组合(且不含5的组合);

同理,我们可以将B2类分成B21和B22两类:B21类是含有3的组合(且不含5、4的组合),B22类是不含3的组合(且不含5、4的组合)。注意,此时B22类是不成立的(应为不含3、4、5,只剩下1、2两个元素。而例子要求解C(5,3)至少需要3个元素)。

以上分类方法可以保证E=B21 U B1 U A

其中,

对于A类组合,我们只需要求解子问题C(4,2),之后再在子问题的结果中加入5即可得到A类组合;

对于B1类组合,我们只需要求解子问题C(3,2),之后再在子问题的结果中加入4即可得到B1类组合;

对于B21类组合,我们只需要求解子问题C(2,2),之后再在子问题的结果中加入3即可得到B21类组合;

A类组合、B1类组合、B21类组合组成了C(5,3)的所有组合。

可以发现,问题C(5,3)已经降维成三个子问题:C(4,2),C(3,2) 和C(2,2)。利用递归的方法即可实现最终结果的求解。

2.2 算法复杂度

2.2.1 时间复杂度

所有的组合算法的时间复杂度都至少是C(n,m)=n!/[m!*(n-m!)]。本算法的时间复杂度也是阶乘量级的。

2.2.2 空间复杂度

由于采用了递归的实现方式,本算法的空间复杂度很高,很有可能造成内存溢出。建议采用非递归的方法实现组合计算。

2.3 源代码

下面是源代码:

/*****************************************************************************************************************************时间复杂度:空间复杂度:功能:求排列组合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.4 测试结果

下面是测试结果:

3 排列算法

排列算法可以采用STL中的next_permutation函数。

4 参考

[1]  http://www.cnblogs.com/shuaiwhu/archive/2012/04/27/2473788.html

C++:排列组合算法相关推荐

  1. python 排列组合速度_Python实现的简单排列组合算法示例

    本文实例讲述了Python实现的简单排列组合算法.分享给大家供大家参考,具体如下: 1.python语言简单.方便,其内部可以快速实现排列组合算法,下面做简单介绍 2.一个列表数据任意组合 主要是利用 ...

  2. 排列组合算法之二: 01转换法_java改变后的c++改进版

    http://blog.csdn.net/canguanxihu/article/details/46363375 排列组合算法之一: 01转换法_java改变后的c++版 class ZuheAss ...

  3. 排列 组合 算法(一)

    排列组合算法 我们都知道排列与组合的个数可以利用公式很容易的求出来,但是要是把这些排列组合的序列一一输出怎么办呢? 下面结合<组合数学>(第四版)卢开澄卢华明编著,好好总结排列与组合的算法 ...

  4. python写排列组合_Python实现的简单排列组合算法示例

    本文实例讲述了Python实现的简单排列组合算法.分享给大家供大家参考,具体如下: 1.python语言简单.方便,其内部可以快速实现排列组合算法,下面做简单介绍 2.一个列表数据任意组合 主要是利用 ...

  5. java 获取排列组合_Java获得一个数组的指定长度排列组合算法示例

    本文实例讲述了Java获得一个数组的指定长度排列组合算法.分享给大家供大家参考,具体如下: package demo; import java.util.Stack; /** * JAVA获得一个数组 ...

  6. js排列组合算法解决方案

    之前文章中谈过排列组合算法,主要事递归,代码如下 const arrangeCombination = arr => {const res = [], len = arr.length, inn ...

  7. C#语法灵活运用之排列组合算法

    今天群里有朋友求一个排列组合算法,题目是给定长度,输出所有指定字母的组合. 如指定字母a.b.c.d.e.f,长度为2,则结果应为:aa.ab.ac ... ef.ff. 有朋友给出算法,很有特色: ...

  8. js实现排列组合算法N选M

    JavaScript 从一个数组中拿出N个数(可放回),问共有多少种 今天在写一道leetcode的时候遇到了无重复放回的遍历问题,用递归解决如下: function p(arr, N, ans){i ...

  9. python 排列组合算法_基于python快速实现排列组合算法

    1.python语言简单.方便,其内部可以快速实现排列组合算法,下面做简单介绍. 2.一个列表数据任意组合 2.1主要是利用自带的库#_*_ coding:utf-8 _*_ #__author__= ...

  10. php 组合算法,PHP简单排列组合算法示例分享

    本文主要和大家介绍了PHP实现的简单排列组合算法,结合具体应用实例分析了排列组合算法的实现与使用技巧,需要的朋友可以参考下,希望能帮助到大家. 一.问题: 给你一个40斤的西瓜,给3个人分,有多少种分 ...

最新文章

  1. POJ 2231 Moo Volume(递推、前缀和)
  2. springDatasolr 排序
  3. Xamarin图表开发基础教程(5)OxyPlot框架
  4. .NET独有的精巧泛型设计模式
  5. 查看linux机器性能,Unix Linux 查看机器性能
  6. Mac中搭建Kubernetes
  7. 安装kali linux 2017.1 【二、安装VMware-tools 以及相关问题处理】
  8. scala 基础十一 scala 中的trait特质
  9. python入门-廖雪峰 Python教程
  10. bzoj 2761: [JLOI2011]不重复数字【hash】
  11. 2017《Java技术》预备作业 杨阳
  12. 计算机同S7-300PLC通讯,西门子S7-300 PLC与Intouch的通讯连接方法
  13. Visio2010如何安装
  14. NOIp2017 题解
  15. snownlp 原理_情感分析snownlp包部分核心代码理解
  16. 怎么查充电器支不支持pd快充协议_新买的iPhone11不能快充?很可能是因为你没用对充电器...
  17. 醉林疯的OJ 1063: 最大公约与最小公倍
  18. 一些常用的第三方平台和开放平台
  19. MTK 9.0平台调试gsensor
  20. iOS RN学习随笔

热门文章

  1. 【MySQL】TIMESTAMPDIFF函数
  2. drupal安装配置错误
  3. 自控力 笔记7 出售未来:及时享乐的经济学
  4. python爬虫之爬取时光网电影影评
  5. Linux线程属性总结 http://blog.csdn.net/zsf8701/article/details/7842392
  6. 三维空间中圆的参数方程
  7. 木马免杀(绕过杀软)
  8. java集成aspose基本使用示例
  9. partial 的用法
  10. IE设置允许活动内容在我的计算机上的文件中运行