C# - Требуется алгоритм для комбинаций Power Set / Sub-Set, но только для фиксированного числа элементов
В порядке,
Это расширение этой проблемы - Супер набор в списке:
Получение всех возможных комбинаций из списка номеров
Это помогает, но возвращает все подмножества: http://rosettacode.org/wiki/Power_set
Но мне нужно получить только те подмножества, которые имеют фиксированное число. Т.е. мой список представляет собой набор чисел:
1 2 3 4 5 6
Мне нужны только разные комбинации для точных 4 чисел, т.е. 1,2,3,4 1,2,3,5 1,2,3,6 1,3,4,5 1,3,4,6 1, 4,5,6 2,3,4,5 2,3,4,6 2,4,5,6 3,4,5,6
Я использую числа в качестве примера, но в своем решении я имею дело с другими типами объектов.
Я на 100% уверен, что это очень легко решить для тех, кто знает....
заранее спасибо
2 ответа
Вы можете расширить решение, на которое вы ссылаетесь, отфильтровав длину результатов
public IEnumerable<IEnumerable<T>> GetPowerSetOfLength<T>(List<T> list, int length)
{
return from m in Enumerable.Range(0, 1 << list.Count)
//because doing a count will iterate through the enumerable
//better to just convert it to a list up front
let setResult = ( from i in Enumerable.Range(0, list.Count)
where (m & (1 << i)) != 0
select list[i]).ToList()
where setResult.Count==length
select setResult;
}
Вот ссылка на скриптовую точку, которая использует этот код, если вы хотите проверить его
Предполагая, что вы всегда хотите ровно 4, это относительно простой алгоритм написания с использованием вложенных циклов for.
var set = new[] {1, 2, 3, 4, 5, 6};
for (int firstIndex = 0; firstIndex < set.Length; firstIndex++)
{
for (int secondIndex = firstIndex+1; secondIndex < set.Length; secondIndex++)
{
for (int thirdIndex = secondIndex+1; thirdIndex < set.Length; thirdIndex++)
{
for (int fourthIndex = thirdIndex+1; fourthIndex < set.Length; fourthIndex++)
{
Console.WriteLine(string.Format($"{set[firstIndex]}, {set[secondIndex]}, {set[thirdIndex]}, {set[fourthIndex]}"));
}
}
}
}
Если вам нужно, чтобы он был динамическим и поддерживал разные размеры списка (т.е. это не всегда 4), то, вероятно, легче преобразовать в рекурсивный вызов, который повторяется N раз.