我几个月来一直试图找到解决方案.这是我的艺术项目.到目前为止,我可以找到部分python和c解决方案,但它们对我的情况没用…我需要一个有效的解决方案,无论是PHP还是Javascript.
这是个问题:
>找到N个数字的所有可能组合,应满足以下条件:
>组合中不重复数字
>其他解决方案中的数字不会以不同的顺序重复
>只使用整数
>在一定范围内的整数
>加起来是X.
例如:
>找到3个数字的所有组合
> 1-12的所有数字
>最多15个
计算出的解决方案应吐出:
[1,2,12]
[1,3,11]
[1,4,10]
[1,5,9]
[1,6,8]
[1,7,7] = EXAMPLE OF WRONG OUTPUT, NO REPEATING NUMBERS WITHIN COMBINATION
[1,8,6] = EXAMPLE OF WRONG OUTPUT, NO REPEATING NUMBERS IN OTHER SOLUTIONS (see [1,6,8])
[2,3,10]
[2,4,9]
[2,5,8]
[2,6,7]
[3,4,8]
[3,5,7]
[4,5,6]
显然这很容易在几分钟内手动完成,但我需要计算更大的范围和更多的数字,所以我需要一个简短的脚本来为我做这个…
任何帮助,将不胜感激!
解决方法:
我觉得应对这一挑战最优雅的方式是通过递归.
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 arrays = getCombos(target - i, i + 1, 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;
}
说明
这可以通过从最小数量i上升到每个数组中的第一项,并将余数(target-i)传递回递归函数以分成n-1个组件,每个递归最小值增加1呼叫.
15 = (1 + 14) = 1 + (2 + 12)
15 = (1 + 14) = 1 + (3 + 11)
15 = (1 + 14) = 1 + (4 + 10)
...
15 = (1 + 14) = 1 + (6 + 8)
15 = (2 + 13) = 2 + (3 + 10)
15 = (2 + 13) = 2 + (4 + 9)
...
15 = (4 + 11) = 4 + (5 + 6)
请注意,每个数组的第一个索引处的数字永远不会超过target / n,其中target是您要求的数字,n是数组中的项目数. (因此,当将15分成3个分量时,第一列将始终小于5.)这也适用于其他列,但随着数组索引的增加,n减少1.知道这一点允许我们递归,而不需要在递归函数上使用额外的参数.
工作实例
查看下面的代码段,看看它的实际效果.
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/>");
};
.table {
display:table;
table-layout:fixed;
width:100%;
}
.table-row {
display:table-row;
}
.cell {
display:table-cell;
}
<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" />