从n个数中取出m个数字的所有情况,用啥算法解决,哪种效率比较高呢

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从n个数中取出m个数字的所有情况,用啥算法解决,哪种效率比较高呢相关的知识,希望对你有一定的参考价值。

参考技术A 从n中选m个数,以下两种方法:
(1)递归
a.
首先从n个数中选取编号最大的数,然后在剩下的n-1个数里面选取m-1个数,直到从n-(m-1)个数中选取1个数为止。
b.
从n个数中选取编号次小的一个数,继续执行1步,直到当前可选编号最大的数为m。
下面是递归方法的实现:
///
求从数组a[1..n]中任选m个元素的所有组合。
///
a[1..n]表示候选集,n为候选集大小,n>=m>0。
///
b[1..M]用来存储当前组合中的元素(这里存储的是元素下标),
///
常量M表示满足条件的一个组合中元素的个数,M=m,这两个参数仅用来输出结果。
void
combine(
int
a[],
int
n,
int
m,
int
b[],
const
int
M
)

for(int
i=n;
i>=m;
i--)
//
注意这里的循环范围

b[m-1]
=
i
-
1;
if
(m
>
1)
combine(a,i-1,m-1,b,M);
else
//
m
==
1,
输出一个组合

for(int
j=M-1;
j>=0;
j--)
cout
<<
a[b[j]]
<<
"
";
cout
<<
endl;



(2)01转换法
本程序的思路是开一个数组,其下标表示1到n个数,数组元素的值为1表示其代表的数被选中,为0则没选中。
首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。
然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为“01”组合,同时将其左边的所有“1”全部移动到数组的最左端。
当第一个“1”移动到数组的n-m的位置,即n个“1”全部移动到最右端时,就得到了最后一个组合。
例如求5中选3的组合:
1
1
1
0
0
//1,2,3
1
1
0
1
0
//1,2,4
1
0
1
1
0
//1,3,4
0
1
1
1
0
//2,3,4
1
1
0
0
1
//1,2,5
1
0
1
0
1
//1,3,5
0
1
1
0
1
//2,3,5
1
0
0
1
1
//1,4,5
0
1
0
1
1
//2,4,5
0
0
1
1
1
//3,4,5

以上是关于从n个数中取出m个数字的所有情况,用啥算法解决,哪种效率比较高呢的主要内容,如果未能解决你的问题,请参考以下文章

C++数学与算法系列之排列和组合

九宫格中,从左下到右上的最短路径,共有几种走法?

TODO:排列组合问题:n个数中取m个

全排列的非递归算法

排列和组合函数

获取所有组合算法获取全排列算法(java)