Skip to main content

元素集内选取组合

m 个元素内选取所有组合

要实现在给定的 m 个元素中选取所有可能的组合,可以使用递归和回溯的方法。以下是一个示例代码:

#include <stdio.h>

void generateCombinations(int arr[], int data[], int start, int end, int index, int r)
{
if (index == r)
{
for (int i = 0; i < r; i++)
{
printf("%d ", data[i]);
}
printf("\n");
return;
}

for (int i = start; i <= end; i++)
{
data[index] = arr[i];
generateCombinations(arr, data, i + 1, end, index + 1, r);
}
}

void printAllCombinations(int arr[], int n)
{
for (int r = 1; r <= n; r++)
{
int data[r];
generateCombinations(arr, data, 0, n - 1, 0, r);
}
}

int main()
{
int arr[] = {1, 2, 3, 4};
int n = sizeof(arr) / sizeof(arr[0]);

printAllCombinations(arr, n);

return 0;
}

在上述代码中,generateCombinations函数使用递归和回溯的方法生成所有可能的组合。它接受一个数组arr,一个辅助数组data用于存储当前组合的元素,startend表示当前递归的起始和结束位置,index表示当前已选取的元素个数,r表示目标选取的元素个数。

在每一层递归中,我们从startend的范围内选择一个元素,并将其存储在data数组中。然后递归调用generateCombinations函数,将start更新为当前选择的元素的下一个位置,index增加 1,继续选择下一个元素。当index等于r时,表示已选取了目标个数的元素,将当前组合打印出来。

printAllCombinations函数中,我们使用一个循环来控制目标选取的元素个数r,从 1 到 n 遍历所有可能的组合。

在示例中,给定数组arr\{1, 2, 3, 4}\,代码会输出所有可能的组合,从 1 个元素到 4 个元素的组合。

你可以根据需要修改数组和元素个数来测试不同的情况。

推广:m 个元素内最多选出 n 个元素,输出组合

#include <stdio.h>

void printCombination(int arr[], int data[], int start, int end, int index, int r)
{
if (index == r)
{
for (int i = 0; i < r; i++)
{
printf("%d ", data[i]);
}
printf("\n");
return;
}

for (int i = start; i <= end && end - i + 1 >= r - index; i++)
{
data[index] = arr[i];
printCombination(arr, data, i + 1, end, index + 1, r);
}
}

void generateCombinations(int arr[], int n, int r)
{
int data[r];
printCombination(arr, data, 0, n - 1, 0, r);
}

int main()
{
int arr[] = {1, 2, 3, 4, 5};
int n = sizeof(arr) / sizeof(arr[0]);
int maxElements = 3;

for (int r = 1; r <= maxElements; r++)
{
printf("Combinations of %d elements:\n", r);
generateCombinations(arr, n, r);
printf("\n");
}

return 0;
}

推广:m 个元素内最少选出 n 个元素,输出组合

如果要输出最少选出 n 个元素的所有组合方式,可以对上述代码进行一些修改。以下是修改后的示例代码:

#include <stdio.h>

void printCombination(int arr[], int data[], int start, int end, int index, int r)
{
if (index == r)
{
for (int i = 0; i < r; i++)
{
printf("%d ", data[i]);
}
printf("\n");
return;
}

for (int i = start; i <= end && end - i + 1 >= r - index; i++)
{
data[index] = arr[i];
printCombination(arr, data, i + 1, end, index + 1, r);
}
}

void generateCombinations(int arr[], int n, int minElements, int maxElements)
{
for (int r = minElements; r <= maxElements; r++)
{
int data[r];
printCombination(arr, data, 0, n - 1, 0, r);
}
}

int main()
{
int arr[] = {1, 2, 3, 4, 5};
int n = sizeof(arr) / sizeof(arr[0]);
int minElements = 2;
int maxElements = 4;

generateCombinations(arr, n, minElements, maxElements);

return 0;
}

在上述代码中,我们添加了一个新的参数minElements,用于指定最少选出的元素个数。generateCombinations函数根据minElementsmaxElements循环调用printCombination函数,从最少选出的元素个数到最多选出的元素个数生成组合。

在示例中,给定数组arr{1,2,3,4,5}\{1, 2, 3, 4, 5\},最少选出 2 个元素,最多选出 4 个元素。代码会输出所有的组合方式,从 2 个元素到 4 个元素的组合。

你可以根据需要修改数组、最少选出的元素个数和最多选出的元素个数来测试不同的情况。

推广:m 个元素内最少选出 p 个元素,最多选出 q 个元素,输出组合

如果要输出最少选出 p 个元素、最多选出 q 个元素的所有组合方式,可以对上述代码进行进一步修改。以下是修改后的示例代码:

#include <stdio.h>

void printCombination(int arr[], int data[], int start, int end, int index, int r)
{
if (index == r)
{
for (int i = 0; i < r; i++)
{
printf("%d ", data[i]);
}
printf("\n");
return;
}

for (int i = start; i <= end && end - i + 1 >= r - index; i++)
{
data[index] = arr[i];
printCombination(arr, data, i + 1, end, index + 1, r);
}
}

void generateCombinations(int arr[], int n, int minElements, int maxElements)
{
for (int r = minElements; r <= maxElements; r++)
{
int data[r];
printCombination(arr, data, 0, n - 1, 0, r);
}
}

int main()
{
int arr[] = {1, 2, 3, 4, 5};
int n = sizeof(arr) / sizeof(arr[0]);
int minElements = 2;
int maxElements = 4;

generateCombinations(arr, n, minElements, maxElements);

return 0;
}

在上述代码中,我们添加了两个新的参数minElementsmaxElements,用于指定最少选出的元素个数和最多选出的元素个数。generateCombinations函数根据minElementsmaxElements循环调用printCombination函数,从最少选出的元素个数到最多选出的元素个数生成组合。

在示例中,给定数组arr{1,2,3,4,5}\{1, 2, 3, 4, 5\},最少选出 2 个元素,最多选出 4 个元素。代码会输出所有的组合方式,从 2 个元素到 4 个元素的组合。

你可以根据需要修改数组、最少选出的元素个数和最多选出的元素个数来测试不同的情况。