Вы можете использовать итеративный и рекурсивный подход для нахождения сумм подмножеств.
Этот подход возвращает два набора из-за двойных.
Он работает, принимая значения измассив или нет.
В главе функции выполняются различные проверки, сначала проверяется, достигнута ли сумма всем элементом во временном массиве t
.Если искомая сумма достигнута, временный массив передается в результирующий набор.
Если индекс имеет значение длины массива, восстановление прекращается.
Последняя проверка выполняетсявперед и, если сумма меньше или равна целевой сумме, элемент с текущим индексом i
берется для следующей рекурсии.
Последний вызов fork
пропускает фактический элемент и отправляетсясо следующим индексом.
tl; dr
Возьмите либо элемент, либо сложите сумму, либо пропустите элемент.Затем перейдите к следующему индексу.
Пример взятых чисел:
7
7 2
7 2 1
7 2 1 5
7 2 1 5 1
7 2 1 5 1
7 2 1 5 1
7 2 1 5
7 2 1 5
7 2 1 5
7 2 1
7 2 1 1
7 2 1 1
7 2 1 1
7 2 1
7 2 1
7 2 1 7
7 2 1
7 2
7 2 5
7 2 5 1
7 2 5 1
7 2 5 1
7 2 5
7 2 5
7 2 5
7 2
7 2 1
7 2 1
7 2 1 7
7 2 1
7 2
7 2
7 2 7
7 2
7
7 1
7 1 5
7 1 5 1
7 1 5 1
7 1 5 1
7 1 5
7 1 5
7 1 5
7 1
7 1 1
7 1 1
7 1 1 7
7 1 1
7 1
7 1
7 1 7
7 1
7
7 5
7 5 1
7 5 1
7 5 1
7 5
7 5
7 5
7
7 1
7 1
7 1 7
7 1
7
7
7 7
7
2
2 1
2 1 5
2 1 5 1
2 1 5 1
2 1 5 1 7
2 1 5 1
2 1 5
2 1 5
2 1 5 7
2 1 5
2 1
2 1 1
2 1 1
2 1 1 7
2 1 1
2 1
2 1
2 1 7
2 1
2
2 5
2 5 1
2 5 1
2 5 1 7
2 5 1
2 5
2 5
2 5 7
2 5
2
2 1
2 1
2 1 7
2 1
2
2
2 7
2
1
1 5
1 5 1
1 5 1
1 5 1 7
1 5 1
1 5
1 5
1 5 7
1 5
1
1 1
1 1
1 1 7
1 1
1
1
1 7
1
5
5 1
5 1
5 1 7
5 1
5
5
5 7
5
1
1
1 7
1
7
function getSubsets(array, sum) {
function fork(i = 0, s = 0, t = []) {
if (s === sum) {
result.push(t);
return;
}
if (i === array.length) {
return;
}
if (s + array[i] <= sum) { // shout circuit for positive numbers only
fork(i + 1, s + array[i], t.concat(array[i]));
}
fork(i + 1, s, t);
}
var result = [];
fork();
return result;
}
console.log(getSubsets([7, 2, 1, 5, 1, 20, 7], 17));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Если хотите, вы можете использовать функцию генератора с еще одним параметром для временного набора результатов.
function* subsets(values, sum, parts = []) {
var i, s;
for (i = 0; i < values.length; i++) {
s = sum - values[i];
if (!s) {
yield [...parts, values[i]];
} else if (s > 0) {
yield* subsets(values.slice(i + 1), s, [...parts, values[i]]);
}
}
}
console.log([...subsets([7, 2, 1, 5, 1, 20, 7], 17)]);
.as-console-wrapper { max-height: 100% !important; top: 0; }