C# - 从对象列表中获取定义长度(或更少)的所有组合

时间:2016-03-31 09:03:23

标签: c# combinations

我有List<Object>。我有一个int maxSize。我想要一个包含maxSize对象的所有组合的List<List<Object>>(这个列表是maxSize,而不是对象)或更少。

我已经看到问题的解决方案看起来像我的问题,除了它们不是我的问题,显然我的大脑不够聪明,无法弄明白。我已经花了3天的时间来解决我的整体问题,试图将自己归结为遗忘,所以我只是在寻找能够在那时工作的解决方案。

要求:

  • 必须返回List<List<Object>>,而不是其他任何内容。
  • 必须以List<Object>和int作为参数。如果它需要更多的递归参数或其他什么,那很好。前两个args仍然是List<Object>和int,而不是其他任何东西。
  • 每个List<Object>只能是maxSize或更小。 “或更少”的要求是可选的,我可以在没有它的情况下工作。
  • 订单无关紧要。 {1,2}等于{2,1}。
  • 不允许重复。如果它包含{1,2},则不能包含{2,1}。

1 个答案:

答案 0 :(得分:1)

这是对我对这个问题的回答的略微修改:
Clean algorithm to generate all sets of the kind (0) to (0,1,2,3,4,5,6,7,8,9)

static IEnumerable<List<T>> Subsets<T>(List<T> objects, int maxLength) {
    if (objects == null || maxLength <= 0)
        yield break;
    var stack = new Stack<int>(maxLength);
    int i = 0;
    while (stack.Count > 0 || i < objects.Count) {
        if (i < objects.Count) {
            if (stack.Count == maxLength)
                i = stack.Pop() + 1;
            stack.Push(i++);
            yield return (from index in stack.Reverse()
                          select objects[index]).ToList();
        } else {
            i = stack.Pop() + 1;
            if (stack.Count > 0)
                i = stack.Pop() + 1;
        }
    }
}

使用示例:

var numbers = new List<int>{1,2,3,4,5};
foreach (var subset in Subsets(numbers, 3)) {
    Console.WriteLine(string.Join("", subset));
}

如果您需要List<List<int>>,只需在结果上调用ToList()