一、以末尾数字为基准,进行组合
【原理】
【核心代码】
//从n个数中抽取r个数的所有组合,a存储n个数,b存储被选中的数的下标
void Combine(int n, int r, int a[],int b[],int R)
{
if (r == 0) //当待抽取的数为0时,待组合的数字个数为0,递归结束
{
int i;
for (i = 0; i < R; ++i)
{
printf("%d ", a[b[i]]);//将被选中的数输出
}
printf("\n");
//count++;此处加上这一句就可以计算输出的组合数的可能
}
else
{
int j;
for (j = n; j >= r; --j)//选定第j个数(固定下来),有5个数,选3个数,按照从后往前的方式选定数字,不重复的情况下只能依次选定5,4,3
{
b[r - 1] = j - 1;//将被选定的数的下标存进去,目的是当a[]是字符数组是也可以灵活应变
Combine(j - 1, r - 1, a, b, R);//从剩下的j-1个数中再抽取r-1个数。选定规则为下一个数的选取范围小于上一个数的集合
}
}
}
【测试调用】
#include <stdio.h>
//从n个数中抽取r个数的所有组合,a存储n个数,b存储被选中的数的下标
void Combine(int n, int r, int a[],int b[],int R)
{
if (r == 0) //待组合的数字个数为0,递归结束
{
int i;
for (i = 0; i < R; ++i)
{
printf("%d ", a[b[i]]);//将被选中的数输出
}
printf("\n");
}
else
{
int j;
for (j = n; j >= r; --j)//选定第j个数(固定下来),有5个数,选3个数,按照从后往前的方式选定数字,不重复的情况下只能依次选定5,4,3
{
b[r - 1] = j - 1;//将被选定的数的下标存进去,目的是当a[]是字符数组是也可以灵活应变
Combine(j - 1, r - 1, a, b, R);//选定规则为下一个数的选取范围小于上一个数的集合
}
}
}
int main()
{
int a[5] = { 1,2,3,4,5 };
int b[3];
Combine(5, 3, a, b, 3);
return 0;
}
【测试结果】
二、以开头数字为基准,进行组合
原理相同
【代码】
#include <stdio.h>
#define N 5
#define R 3
void Combine(int start, int r, int a[], int b[])
{
if (r > N)
{
int i;
for (i = 0; i < R; ++i)
{
printf("%d", a[b[i]]);
}
printf("\n");
}
else
{
int j;
for (j = start; j <= r; ++j)
{
b[r - 3] = j - 1;
Combine(j + 1, r + 1, a, b);
}
}
}
int main()
{
int a[N] = { 1,2,3,4,5 };
int b[R];
Combine(1, R, a, b);
return 0;
}
【测试结果】