Алгоритм:
- Количество от 1 до 2 ^ n.
- Преобразование каждой цифры в ее двоичное представление.
- Переведите каждый бит 'on' в элементы вашего набора на основе позиции.
В C #:
void Main()
{
var set = new [] {"A", "B", "C", "D" }; //, "E", "F", "G", "H", "I", "J" };
var kElement = 2;
for(var i = 1; i < Math.Pow(2, set.Length); i++) {
var result = Convert.ToString(i, 2).PadLeft(set.Length, '0');
var cnt = Regex.Matches(Regex.Escape(result), "1").Count;
if (cnt == kElement) {
for(int j = 0; j < set.Length; j++)
if ( Char.GetNumericValue(result[j]) == 1)
Console.Write(set[j]);
Console.WriteLine();
}
}
}
Почему это работает?
Существует биекция между подмножествами n-элементного набора и n-битных последовательностей.
Это означает, что мы можем выяснить, сколько существует подмножеств путем подсчета последовательностей.
например, четыре элемента, представленные ниже, могут быть представлены {0,1} X {0, 1} X {0, 1} X {0, 1} (или 2 ^ 4) различными последовательностями.
Итак - все, что нам нужно сделать, это сосчитать от 1 до 2 ^ n, чтобы найти все комбинации. (Мы игнорируем пустое множество.) Затем переведите цифры в их двоичное представление. Затем замените элементы вашего набора на «включенные» биты.
Если вы хотите получить только k элементов, выведите их только тогда, когда k битов включены.
(Если вы хотите, чтобы все подмножества вместо k подмножеств длины, удалите часть cnt / kElement.)
(в качестве доказательства см. Бесплатное программное обеспечение MIT по математике для информатики, Lehman et al., Раздел 11.2.2. https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-042j-mathematics-for-computer-science-fall-2010/readings/)