【问题标题】:how do I get all combinations of elements in a list?如何获取列表中元素的所有组合?
【发布时间】:2017-11-07 03:39:01
【问题描述】:

在获取 X 元素列表时,如何获取这些元素的所有双精度、三倍、... ( Y ) 组合?
Y 是所需组合的大小。例如:如果 Y = 2,我需要得到所有可能的对。
我不能两次给出相同的组合(例如:[a, b] 和 [b, a] 是相同的组合)

【问题讨论】:

标签: c++ algorithm combinations combinatorics


【解决方案1】:

复制一份清单。

如果列表为空,则没有组合。

要获得大小为 1 的所有组合,请依次查看每个元素。

要获得所有大小为 n+1 的组合,首先删除第一个元素。然后获取列表其余部分的大小为 n 的所有组合,加上第一个元素。然后获取列表其余部分大小为 n+1 的所有组合,并且不添加第一个元素。

然后你就完成了。

为了优化,你可以变得花哨,只是假装复制/删除元素。

【讨论】:

  • 我应该使用递归是数组的大小等于或大于 2 吗?它如何让我避免重复?为了避免它们,我必须一一删除所有元素吗?
【解决方案2】:

您可以将 t 从 2 迭代到 Y,并创建一个大小为 X 的数组 A,前面填充 X-t 0,后面填充 t 1,然后使用以下代码:

do{
    //1s in array A now correspond to a valid combination
}while(std::next_permutation(A,A+X));

当所有大小为 t 的组合被迭代时,循环将停止

next_permutation 在标头算法中,它会将数组重新排序到下一个字典顺序更大的排列,或者如果数组已经在字典顺序上最大的排列中,则返回 false。它的复杂度是 O(n),因为您还需要遍历数组一次,所以这不是问题。整个过程的总复杂度将以 O(2^n*n) 为界。

所以这里是一个示例伪代码

D[X] = {1,2,3,4} Y = 3 //the input
For t = 2,3,..,Y
    A[X] = {0,...,0,1,...,1} // X - t 0s and t 1s 
    Do
        For j = 0,1,...,X-1
            if A[j] == 1
                output D[j]
            end if
        end for
        output newline
    While next_permutation(A,A+X)
end for

输出看起来像

3 4
2 4
2 3
1 4
1 3
1 2
2 3 4
1 3 4
1 2 4
1 2 3

【讨论】:

  • 这适用于结构吗?这是否允许我只有独特的组合? (并且结果中没有 [a, b] 和 [b, a] )
  • 因为它会在字典上产生更大的排列,所以它不会给出相同的排列。
  • 是的,它适用于结构,因为只有 0 和 1 被置换。
  • 但是我该如何使用它呢?如何选择所需组合的大小?我怎样才能在循环中访问它们?如果我理解(很确定我不理解),我会得到所有组合,无论大小如何,都必须忽略不符合所需大小的组合,女巫似乎效率不高
  • 首先,外部 for 循环将遍历您想要的所有组合大小(例如 2,3,...,Y),然后在另一个数组的后面填充相同数量的 1。使用上面的 do 循环,您将获得具有此大小的所有可能组合,每个组合一次。假设数组看起来像 {0,1,0,1,1},那么这意味着由第二个、第四个和第五个元素组成的组合。您不必忽略其中任何一个,因为它们都满足您的需求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-29
  • 1970-01-01
  • 2010-10-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多