实验问题:
不超过n的r组合,且组合不能重复
问题分析:
共有r个位置可以放数,从大数到小数放;
第r个位置可以固定数 n,n-1,n-2…i…n-r(i>=r);
第r-1个位置可以固定数 i-1,i-2…i-r-1(对于i);
依次类推,到最后一个位置即r=1时可以固定数 i,i-1…1。
数学建模:
建立函数comb(n,r) n代表几个数,r代表几个组合;
先固定第一个数:可以为n,n-1…i…n-r;
再固定后r-1个数:comb(i-1,r-1);只需从小于i-1的数中选择;
递归出口是:r<=1。
实现代码:
#define _CRT_NO_SECRUE_WARNINGS
#include<stdio.h>
#include<iostream>
using namespace std;
int a[100] = {};
int num = 0;
void comb(int n, int r) {
for (int i = n;i >= r;i--) {
a[r] = i;
if (r > 1) {
comb(i - 1, r - 1);
}
else {
for (int j = a[0]; j > 0;j--) {
cout << a[j];
}
cout << "\n";
num++;
}
}
return;
}
int main() {
int n = 0;
int r = 0;
cout << "请输入n:";
cin >> n;
cout << "请输入r:";
cin >> r;
if (r > n) {
cout << "ERROR";
return 0;
}
a[0] = r;
cout << "组合形式为:"<<endl;
comb(n, r);
cout << "组合个数为:" << num << endl;
system("pause");
return 0;
}
测试数据:
n=6
r=3
实验结果:
时间复杂度:
递归深度是r,执行comb(n,k)要递归n-k+1次
时间复杂度为O(n)