С# (математика, комбинторика) перебор всех подмножеств данного множества
У меня есть список чисел небольшой (длина <= 5 элементов). Мне нужно разбить его на под-списки (или массивы) которые будут содержать все варианты пар, троек, четвёрок чисел без повторений (порядок не имеет значения).
Пример для списка [a, b, c, d, e]:
- Список одиночных чисел и есть исходный список [a, b, c, d, e] - 5 элементов
- Список пар [ [a,b], [a,c], [a,d], [a,e], [b,c], [b,d], [b,e], [c,d], [c,e], [d,e] ] - 10 элементов
- Список троек [ [a,b,c], [a,b,d], [a,b,e], [a,c,d], [a,c,e], [a,d,e], [b,c,d], [b,c,e], [b,d,e], [c,d,e] ] - 10 элементов
- Список четвёрок [ [a,b,c,d], [a,b,c,e], [a,b,d,e], [a,c,d,e], [b,c,d,e] ] - 5 элементов
- Список пятёрок (токо одна возможна) [ [a,b,c,d,e] ] - 1 элемент
Не могу понять как сделать универсальный перебор для любого размера и что бы не расписывать в кучу строк. Спасибо заранее)
UPD: прикрепил ответ с готовым цыклом
Ответы (1 шт):
Автор решения: KuzCode
→ Ссылка
Вот, что у меня получилось в результате:
char[] arr = new char[]{'a','b','c','d','e'};
var result = new List<List<char>>();
for (int mask = 0; mask < (1 << arr.Length); mask++)
{ //перебор масок
result.Add(new List<char>());
for (int j = 0; j < arr.Length; j++) //перебор индексов массива
{
if((mask & (1 << j)) != 0) //поиск индекса в маске
{
result.Last().Add(arr[j]); // добавление элемента
Console.Write(arr[j] + " "); //вывод элемента
}
}
Console.WriteLine(); //перевод строки для вывод следующего подмножества
}
Вывод:
a
b
a b
c
a c
b c
a b c
d
a d
b d
a b d
c d
a c d
b c d
a b c d
e
a e
b e
a b e
c e
a c e
b c e
a b c e
d e
a d e
b d e
a b d e
c d e
a c d e
b c d e
a b c d e
Что бы не создавался массив с нулевой длинной можно изменить стартовое значение mask на 1.