У меня есть сценарий, который дает мне все возможные комбинации набора чисел, добавляемых к числу. Но я не хочу минимального или максимального числа, но я хочу, чтобы иметь возможность вводить числа, которые мне нужны. Таким образом, моя цель может быть "3", а набор содержит числа 1 и 2. Как вы можете видеть, я также хочу иметь все возможные порядки, и каждый номер можно использовать более одного раза. Результатом в этом случае будет: 1+1+1, 2+1, 1+2
. Я также хочу, чтобы количество результатов отображалось.
<!DOCTYPE html>
<html>
<head>
<title>Sum</title>
</head>
<body>
<style>
.table {
display: table;
table-layout: fixed;
width: 100%;
}
.table-row {
display: table-row;
}
.cell {
display: table-cell;
}
</style>
<div class="table">
<div class="table-row">
<div class="cell">Target:</div>
<div class="cell">
<input id="target" type="text" value=15>
</div>
<div class="cell">n:</div>
<div class="cell">
<input id="n" type="text" value=3>
</div>
</div>
<div class="table-row">
<div class="cell">Min:</div>
<div class="cell">
<input id="min" type="text" value=1>
</div>
<div class="cell">Max:</div>
<div class="cell">
<input id="max" type="text" value=12>
</div>
</div>
</div>
<input id="submit" type="button" value="submit" />
<div id="output" />
<script>
function getCombos(target, min, max, n) {
var arrs = [];
if (n === 1 && target <= max) {
arrs.push([target]);
} else {
for (var i = min; i < target / n && i <= max; i++) {
var nextTarget = target - i;
var nextMin = i + 1;
var arrays = getCombos(nextTarget, nextMin, max, n - 1);
for (var j = 0; j < arrays.length; j++) {
var array = arrays[j];
array.splice(0, 0, i);
arrs.push(array);
}
}
}
return arrs;
}
document.getElementById("submit").onclick = function() {
var target = document.getElementById("target").value;
var min = document.getElementById("min").value;
var max = document.getElementById("max").value;
var n = document.getElementById("n").value;
var result = getCombos(+target, +min, +max, +n);
document.getElementById("output").innerHTML = result.join("<br/>");
};
</script>
</body>
</html>
Как отмечалось в комментариях, это версия проблемы подмножества сумм (но вместо суммирования на 0
вы суммируете на некоторое требуемое число).
На странице Википедии есть O(2 ^ (n/2))
, однако, поскольку ваши входы кажутся маленькими, я просто реализую алгоритм грубой силы O(2 ^ N * N)
чтобы решить эту проблему.
function get_summing_subsets(set_arr, target){
let finish = [];
let working = [[]];
while (working.length){
let next_work = [];
for (let i = 0; i < working.length; i++){
for (let j = 0; j < set_arr.length; j++){
let subset = working[i].concat([set_arr[j]]);
let sum = subset.reduce((a,b) => a + b, 0);
if (sum <= target){
(sum == target ? finish : next_work).push(subset);
}
}
}
working = next_work
}
return finish;
}
который хорошо работает:
//your example
get_summing_subsets([1,2], 3)
[[1,2],[2,1],[1,1,1]]
//another
get_summing_subsets([1,2,3], 4)
[[1,3],[2,2],[3,1],[1,1,2],[1,2,1],[2,1,1],[1,1,1,1]]
<script>
а затем либо console.log(get_summing_subsets([1,2], 3))
либо задайте текст некоторого элемента с таким результатом