参考以下这篇博文,在这个基础上进行了一些改进,可以去除组合数中的重复项。
参考博文:http://blog.csdn.net/dremi/article/details/1940723
改进后的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 |
#include <iostream> using
namespace std; void
com( int
*arr, int
idx[], int
start, int
cnt, const
int &m, const
int &n) { if (start + cnt > m) return
; if (cnt == 0) //cnt为0 表示选取了n个元素了,即找到了一个组合. { for ( int
i = 0; i < n; i++) cout<<arr[idx[i]]<< " " ; cout<<endl; return ; } //检查当前的元素在之前是否被选择过 bool
exist = false ; for ( int
i=0;i<=n-cnt;++i ) if ( idx[i]!=-1 && arr[idx[i]] == arr[start]) exist = true ; if ( exist== false
) { //把start选中 idx[n - cnt] = start; com(arr,idx,start + 1, cnt - 1, m, n); } else { com(arr ,idx, start+1, cnt,m,n); } //当前不选择start位置的元素,在 剩下的元素中选择cnt个数。 if (start + cnt < m) com(arr,idx, start + 1, cnt, m, n); } ////////////////////////////////////////////////////////////////////////// // idx[] : 用来记录组合下标 // m : 要组合元素的总个数 // n : 要选取的元素个数. // 如: p(6, 5) 表示从6个元素中选取5个 则: m=6, n=5 ////////////////////////////////////////////////////////////////////////// void
combine( int
*arr, int
idx[], const
int &m, const
int &n) { if (n <= m && n > 0) com(arr,idx, 0, n, m, n); } int
main() { int
index[20],m,n; int
arr[5]={1,2,2,4,5}; memset (index,255, sizeof (index)); while (cin>>m>>n) { // 5 3 combine(arr,index, m, n); } return
0; } |
原文:http://www.cnblogs.com/jesse-deng/p/3603230.html