C/C++ 用递归实现排列组合

// 排列组合.cpp
#include <iostream>

#define MAXN 1000
#define MAXM 1000

using namespace std;

int N, M, a[MAXN]; // a[]为输入的原始数组
int cnt_C, cnt_P, cnt_A; // 分别计数:组合情况,全排列情况,排列组合情况
bool is_A; // 是否进行排列组合

void print(int array[], int n) { // 输出函数
	for (int i = 1; i <= n; i++) 
	  cout << array[i] << " ";
	cout << endl;
}

全排列函数:P(N)

// 全排列函数 P(N) - 将 N个元素全排列
// 主函数里调用 Perm(a, 1, N)
// Permutation
void Perm(int aa[], int l, int r) { // Perm(aa[], l, r):将 aa[]从 l到 r进行全排列
	if (l == r) { // 完成一种情况
		if (is_A) { cnt_A++; print(aa, M); return;}
		cnt_P++; print(aa, N); return;
	}
	
	// 将第 i个元素与第 l个交换,进行递归
	for (int i = l; i <= r; i++) { // i从 l开始往后枚举
		int t = aa[l]; aa[l] = aa[i], aa[i] = t; // 交换 aa[l]与 aa[i]
		Perm(aa, l + 1, r); // 全排列 aa[l+1]到 aa[r]
		t = aa[l]; aa[l] = aa[i], aa[i] = t; // 换回 aa[l]与 aa[i]
	}
}

组合函数:C(N,M)

// 组合函数:C(N, M) - 从 N个里面取 M个
// 主函数里调用:Com(M, 1, N)
int com[MAXM], tail = 0;
// Combination
void Com(int m, int l, int r) { // Com(m, l, r):从 l到 r中取 m个 
	if (!m) { // 即 tail == M,完成一种情况
		if (is_A) { Perm(com, 1, M); return;}
		cnt_C++; print(com, M); return; 
	} 
	
	// i从 l开始往后枚举
	for (int i = l; i <= r; i++) { 
		com[++tail] = a[i]; // 取第 i个
		Com(m - 1, i + 1, r); // 从 i+1到 r中取 m-1个
		tail--; // 放回第 i个
	}
}

主函数 main()

int main() { 
	cin >> N >> M;
	for (int i = 1; i <= N; i++) cin >> a[i];
	cout << endl;
	// 组合 C(N, M)
	cout << "Combination:" << endl;
	cnt_C = 0, is_A = false;
	Com(M, 1, N);
	cout << "Situations: " << cnt_C << endl << endl;
	// 全排列 P(N)
	cout << "Permutation:" << endl;
	cnt_P = 0, is_A = false;
	Perm(a, 1, N);
	cout << "Situations: " << cnt_P << endl << endl;
	// 排列组合 A(N, M)
	cout << "Com & Perm:" << endl;
	cnt_A = 0, is_A = true;
	Com(M, 1, N);
	cout << "Situations: " << cnt_A << endl;
	
	return 0;
}

输入:

4 3
1 2 3 4

输出:

4 3
1 2 3 4

Combination:
1 2 3
1 2 4
1 3 4
2 3 4
Situations: 4

Permutation:
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 3 2
1 4 2 3
2 1 3 4
2 1 4 3
2 3 1 4
2 3 4 1
2 4 3 1
2 4 1 3
3 2 1 4
3 2 4 1
3 1 2 4
3 1 4 2
3 4 1 2
3 4 2 1
4 2 3 1
4 2 1 3
4 3 2 1
4 3 1 2
4 1 3 2
4 1 2 3
Situations: 24

Com & Perm:
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
3 1 2
1 2 4
1 4 2
2 1 4
2 4 1
4 2 1
4 1 2
1 3 4
1 4 3
3 1 4
3 4 1
4 3 1
4 1 3
2 3 4
2 4 3
3 2 4
3 4 2
4 3 2
4 2 3
Situations: 24

--------------------------------
Process exited after 4.408 seconds with return value 0
请按任意键继续. . .
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值