【c++】组合问题

C m n C_m^n Cmn

C m n = m ! n ! ( m − n ) ! C_m^n=\dfrac{m!}{n!(m-n)!} Cmn=n!(mn)!m! m > n m>n m>n

枚举法

#include <iostream>

using namespace std;

int main(int argc, char** argv)
{
    int m = 8;
    int n = 4;
	
    for(int i = 0; i < m-3; i++)
    {
		for(int j = i+1; j < m-2; j++)
        {
			for(int k = j+1; k < m-1; k++)
            {
                for(int h = k+1; h < m; h++)
                {
                    cout<< i << " " << j << " " << k << " " << h <<endl;
                }
			}
		}
	}
}

程序输出如下:

0 1 2 3
0 1 2 4
0 1 2 5
0 1 2 6
0 1 2 7
0 1 3 4
0 1 3 5
0 1 3 6
0 1 3 7
0 1 4 5
0 1 4 6
0 1 4 7
0 1 5 6
0 1 5 7
0 1 6 7
0 2 3 4
0 2 3 5
0 2 3 6
0 2 3 7
0 2 4 5
0 2 4 6
0 2 4 7
0 2 5 6
0 2 5 7
0 2 6 7
0 3 4 5
0 3 4 6
0 3 4 7
0 3 5 6
0 3 5 7
0 3 6 7
0 4 5 6
0 4 5 7
0 4 6 7
0 5 6 7
1 2 3 4
1 2 3 5
1 2 3 6
1 2 3 7
1 2 4 5
1 2 4 6
1 2 4 7
1 2 5 6
1 2 5 7
1 2 6 7
1 3 4 5
1 3 4 6
1 3 4 7
1 3 5 6
1 3 5 7
1 3 6 7
1 4 5 6
1 4 5 7
1 4 6 7
1 5 6 7
2 3 4 5
2 3 4 6
2 3 4 7
2 3 5 6
2 3 5 7
2 3 6 7
2 4 5 6
2 4 5 7
2 4 6 7
2 5 6 7
3 4 5 6
3 4 5 7
3 4 6 7
3 5 6 7
4 5 6 7

枚举法 n n n是几,就要设计执行几次循环。只适用于 n n n值固定的情况

递归法

#include <iostream>
#include <vector>

using namespace std;


/*
参数一:数据
参数二:要求组合的个数
参数三:数据总个数
参数四:存放一个组合结果索引值的临时数组
参数五:要求组合的个数
参数六:最终结果*/
void combine(int data[], int n, int m, int temp[], const int N, vector<vector<int> > &result)
{
	for(int i=m; i>=n; i--)  
	{
		temp[n-1] = i - 1;
		if (n > 1)
		    combine(data, n-1, i-1, temp, N, result);
		else          
		{
			vector<int > vec_temp;
		    for(int j=N-1; j>=0; j--)
            {
				vec_temp.push_back(data[temp[j]]);
		    }
		    result.push_back(vec_temp);
		}
	}
}

int main(int argc, char** argv)
{
	// 数据总数为m
    int m = 8;
	// 任意n个组合
    int n = 4;
	
	// 最终结果存放
    vector<vector<int> > result;

	// 数据数组
    int data[8] = {0, 1, 2, 3, 4, 5, 6, 7};
    
	// 临时存放数据索引值的数组
	int temp[4];
    
	combine(data, n, m, temp, n, result);

	// 打印结果	
	for(int i = 0; i<result.size(); i++)
    {
	    for(int j = 0; j<4; j++)
        {
			cout<<result[i][j]<<" ";
		}
		cout<<endl;
	} 
}

程序输出如下:

7 6 5 4
7 6 5 3
7 6 5 2
7 6 5 1
7 6 5 0
7 6 4 3
7 6 4 2
7 6 4 1
7 6 4 0
7 6 3 2
7 6 3 1
7 6 3 0
7 6 2 1
7 6 2 0
7 6 1 0
7 5 4 3
7 5 4 2
7 5 4 1
7 5 4 0
7 5 3 2
7 5 3 1
7 5 3 0
7 5 2 1
7 5 2 0
7 5 1 0
7 4 3 2
7 4 3 1
7 4 3 0
7 4 2 1
7 4 2 0
7 4 1 0
7 3 2 1
7 3 2 0
7 3 1 0
7 2 1 0
6 5 4 3
6 5 4 2
6 5 4 1
6 5 4 0
6 5 3 2
6 5 3 1
6 5 3 0
6 5 2 1
6 5 2 0
6 5 1 0
6 4 3 2
6 4 3 1
6 4 3 0
6 4 2 1
6 4 2 0
6 4 1 0
6 3 2 1
6 3 2 0
6 3 1 0
6 2 1 0
5 4 3 2
5 4 3 1
5 4 3 0
5 4 2 1
5 4 2 0
5 4 1 0
5 3 2 1
5 3 2 0
5 3 1 0
5 2 1 0
4 3 2 1
4 3 2 0
4 3 1 0
4 2 1 0
3 2 1 0

结语

如果您有修改意见或问题,欢迎留言或者通过邮箱和我联系。
手打很辛苦,如果我的文章对您有帮助,转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值