我有一个脚本,可以为我提供一组数字的所有可能组合,这些数字加起来就是一个数字。但是我不希望有最小或最大数字,但是我希望能够输入所需的数字。因此,我的目标可能是“ 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 :(得分:1)
正如评论中所指出的,这是subset-sum problem的一个版本(但不是求和为0
,而是求和一些期望的数字)。
Wikipedia页面确实给出了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]]