组合算法


#include 
<iostream>

using namespace  std;
//
//
 功能 :    从0....m中选取n个的所有组合
//
 idx[]:    用来记录一个组合, 如: 0,1,3表示选取的是第1,2,4个元素的组合
//
 start:    起始下标
//
 cnt  :    剩下还要组合元素的个数
//
 备注:
//
 此算法的思想是: 要从0...m中选取n个元素的组合, 可以问题分解为:把0选进来, 然后再在1...m中选取
//
 n-1个元素, 和没有把0选进来, 在1...m中选取n个元素.
//
 然后: 用同样的办法,分解从1...m中选取的n-1个元素的组合.
//
 例如: 从0 1 2 3 中选取3个算法
//
 首先: start从0,  cnt = 3, com(idx,0, 3, 4, 3); 首先把0选中, 剩下的从1 2 3 中选取2个的组合.即为com(idx,1,2,4,3)
//
 若不把0选上,即从1 2 3 中选3个即:com(idx, 1, 3, 4, 3);

// 从m个元素中选取n个的的组合, 这里只是生成下标组合,即不是具体元素的组合.

//

void com(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
<<idx[i]<<" "
;
        cout
<<
endl;
        
return
;
    }

    
//把start选中
    idx[n - cnt] = start;
    com(idx,start 
+ 1, cnt - 1
, m, n);

    
if(start + cnt <
 m)
        com(idx, start 
+ 1
, cnt, m, n);
}


//
//
 idx[] : 用来记录组合下标
//
 m     : 要组合元素的总个数
//
 n     : 要选取的元素个数.
// 如: p(6, 5) 表示从6个元素中选取5个 则: m=6, n=5

//

void combine(int idx[], const int &m, const int & n)
{
    
if(n <= m && n > 0
)
        com(idx, 
0
, n, m, n);
}


int  main()
{
    
int index[20
],m,n;
    
while(cin>>m>>
n)
    
{
        combine(index, m, n);
    }
        
    
return 0
;
}


/************************************************************************/
/* 测试用例:
6 4

0 1 2 3
0 1 2 4
0 1 2 5
0 1 3 4
0 1 3 5
0 1 4 5
0 2 3 4
0 2 3 5
0 2 4 5
0 3 4 5
1 2 3 4
1 2 3 5
1 2 4 5
1 3 4 5
2 3 4 5                                                                  
*/

/************************************************************************/

如果是想要输出具体元素的值,如从数组char a[4] = a b c d 中选3个的组合, 因为上面是考虑下标组合, 只要在输出是把idx[i]设为 a[idx[i]] 即可. 不过这里组合没有考虑元素中有重复的情况.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值