Как найти все подмножества набора в JavaScript?

мне нужно получить все возможные подмножества массива.

скажи, что у меня есть это:

[1, 2, 3]

Как я могу сделать это?

[], [1], [2], [1, 2], [2, 3], [1, 3], [1, 2, 3]

меня интересуют все подмножества. Для подмножеств определенной длины обратитесь к следующим вопросам:

  • Поиск подмножеств размера n: 1, 2
  • Поиск подмножеств размера > 1:1

4 ответов


вот еще одно очень элегантное решение без циклов или рекурсии, только с использованием карты и уменьшения собственных функций массива.

const getAllSubsets = 
      theArray => theArray.reduce(
        (subsets, value) => subsets.concat(
         subsets.map(set => [value,...set])
        ),
        [[]]
      );

console.log(getAllSubsets([1,2,3]));

мы можем решить эту проблему для подмножества входного массива, начиная с offset. Затем мы возвращаемся назад, чтобы получить полное решение.

С помощью функции генератора позволяет нам перебирать подмножества с постоянным использованием памяти:

// Generate all array subsets:
function* subsets(array, offset = 0) {
  while (offset < array.length) {
    let first = array[offset++];
    for (let subset of subsets(array, offset)) {
      subset.push(first);
      yield subset;
    }
  }
  yield [];
}

// Example:
for (let subset of subsets([1, 2, 3])) {
  console.log(subset); 
}

сложность выполнения пропорциональна числу решений (2ⁿ), умноженному на среднюю длину решения (n/2) = O (n2ⁿ).


другое простое решение.

function getCombinations(array) {

    function fork(i, t) {
        if (i === array.length) {
            result.push(t);
            return;
        }
        fork(i + 1, t.concat([array[i]]));
        fork(i + 1, t);
    }

    var result = [];
    fork(0, []);
    return result;
}

var data = [1, 2, 3],
    result = getCombinations(data);
	
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Вы можете легко создать множество из массива, используя что-то вроде следующего:

var arr = [1, 2, 3];

function generatePowerSet(array) {
  var result = [];
  result.push([]);

  for (var i = 1; i < (1 << array.length); i++) {
    var subset = [];
    for (var j = 0; j < array.length; j++)
      if (i & (1 << j))
        subset.push(array[j]);

    result.push(subset);
  }

  return result;
}

console.log(generatePowerSet(arr));

по всему основному циклу функции создаются подмножества, а затем помещаются в result массив.