您如何以编程方式将一组数字的所有可能唯一组合枚举为多个组?
例如,如果我有集合{1,2,3,4,5,6,7,8,9,10}并且我想要3个大小为3,3,2的组,则一个可能的子集将是{ [1,2,3],[4,5,6],[7,8]}
这相当于{[3,2,1],[6,5,4],[7,8]}并且会被视为重复
而{[4,2,3],[1,5,6],[7,8]}将被视为不同的子集
显然,我正在寻找最有效和实用的方法。我将使用相当大的N,因此算法需要可扩展。
答案 0 :(得分:1)
另一种思考这个问题的方法是作为多集的排列
{1, 1, 1, 2, 2, 2, 3, 3}
。如果此类排列p
在位置i
中的值为j
,则表示原始集合中的元素j
应放在分区i
中。
使用例如您可以按如下方式枚举这些排列的C ++模板next_permutation
:
int main() {
int a[] = { 0, 0, 0, 1, 1, 1, 2, 2 };
do {
// Here a[j] == i means element j of your set goes in partition i.
// Do whatever you want to do with the permutations generated this way.
} while (std::next_permutation(a, a + 8));
}
结果将包含10!/(3!3!2!)= 560种不同的组合。此代码的演示运行(包括类似于问题陈述中使用的符号的输出)为available at ideone。如果您想知道如何为gcc实现next_permutation
,可以查看the source code,但只有在目标项目的许可证允许复制该代码时才能这样做。