参考以下这篇博文,在这个基础上进行了一些改进,可以去除组合数中的重复项。
参考博文:http://blog.csdn.net/dremi/article/details/1940723
改进后的代码如下:
#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; }