C# - 从对象列表中获取定义长度(或更短)的所有组合
C# - Get all combinations of defined length (or less) from a list of objects
我有一个List<Object>
。我有一个 int maxSize。我想要一个 List<List<Object>>
包含 maxSize 对象的所有组合(此列表是 maxSize,而不是对象),或更少。
我见过看起来像我的问题的解决方案,但它们不是我的问题,显然我的大脑不够聪明,无法解决。我也已经花了 3 天的时间来解决我的整体问题,试图将自己递归到遗忘中,所以我只是在寻找在那个时候才有效的解决方案。
要求:
- 它必须 return 一个
List<List<Object>>
,而不是其他任何东西。
- 它必须以
List<Object>
和 int 作为参数。如果它需要更多的递归参数或其他参数,那很好。前两个参数仍然是 List<Object>
和一个 int,没有别的。
- 每个
List<Object>
只能是 maxSize 或更小。 "or less" 要求是可选的,没有它我也可以工作。
- 顺序无关紧要。 {1,2} 等于 {2,1}。
- 不允许重复。如果包含{1,2},则不能包含{2,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()
。
我有一个List<Object>
。我有一个 int maxSize。我想要一个 List<List<Object>>
包含 maxSize 对象的所有组合(此列表是 maxSize,而不是对象),或更少。
我见过看起来像我的问题的解决方案,但它们不是我的问题,显然我的大脑不够聪明,无法解决。我也已经花了 3 天的时间来解决我的整体问题,试图将自己递归到遗忘中,所以我只是在寻找在那个时候才有效的解决方案。
要求:
- 它必须 return 一个
List<List<Object>>
,而不是其他任何东西。 - 它必须以
List<Object>
和 int 作为参数。如果它需要更多的递归参数或其他参数,那很好。前两个参数仍然是List<Object>
和一个 int,没有别的。 - 每个
List<Object>
只能是 maxSize 或更小。 "or less" 要求是可选的,没有它我也可以工作。 - 顺序无关紧要。 {1,2} 等于 {2,1}。
- 不允许重复。如果包含{1,2},则不能包含{2,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()
。