用递归实现:
1.确定要取的每个组合的元素个数;
2.对于每个组合,按照索引大小,先取第一个,此时要取的个数减 1,
3.按照第二步的逻辑重复,直至一个完成组合取值;
4.下一个组合重复第2,3步.
或者可以这样说:
例如每个组合要在 {1, 2, 3, 4, 5} 取 3 个数,
第一个数可以取 1, 2 或 3(4, 5 不能取是因为每个组合要 3 个数), 假设取 n( n <= 5 - 2).
第二个数就可以在 [n+1 5]中取一个值 m(m <= 5 -1)
第三个可以在 [m+1 5] 取一个值,这样就可以组成一个组合
这个逻辑类似数据结构中的 树, 第一个数取 1 , 子树则有 2, 3,4
子树取 2, 子树的子树则有 3, 4, 5.
#include <stdio.h>
/**
@param arr 数组
@param length 数组长度
@param start 遍历开始索引
@param getcount 需要取的组合里的元素个数
@param tempArr 每个组合的数据缓存
@param tempLength 组合的长度
@param total 组合个数
*/
void printCombination(int *arr, const int length, int start, int getcount, int *tempArr, const int tempLength, int *total) {
if(getcount == 0) { //对应第 3 步, 此时打印出一个组合
(*total)++;
for(int index = 0; index < tempLength; index++) {
printf("%d ", tempArr[index]);
}
printf("\n");
return;
}
if(getcount > (length - start) || tempLength < getcount || getcount < 1) {//
return;
}
for(int i = start; i < length; i++) {
tempArr[tempLength - getcount] = arr[i];//对应第 2 步
printCombination(arr, length, i + 1, getcount - 1, tempArr, tempLength, total);
}
}
int main(int argc, char *argv[]) {
int a = 0;
int *total = &a;
int arr[] = {1, 2, 3, 4, 5, 6};
int temp[] = {0, 0, 0};
printCombination(arr, 6, 0, 4, temp, 4, total);
printf("total: %d \n", (int)*total);
}
打印结果
1 2 3 4
1 2 3 5
1 2 3 6
1 2 4 5
1 2 4 6
1 2 5 6
1 3 4 5
1 3 4 6
1 3 5 6
1 4 5 6
2 3 4 5
2 3 4 6
2 3 5 6
2 4 5 6
3 4 5 6
total: 15
网友评论