有一组常量:[1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
。
我必须输入任何自然数(正整数)并从上面的设置中按降序输出其数字的总和。
例如:3497 => [512, 512, 512, 512, 512, 512, 256, 128, 32, 8, 1]
。
我该怎么做? 我可以理解递归算法可以处理问题,但我不太擅长递归。
感谢您的帮助!
答案 0 :(得分:5)
对于任何值,您可以使用组合方法,对具有相关较小值集的函数进行迭代和递归调用。
function combine(array, sum) {
function c(left, right, sum) {
if (!sum) {
result = right;
return true;
}
return left.some(function (a, i, aa) {
return a <= sum && c(aa.slice(i + (a > sum - a)), right.concat(a), sum - a);
});
}
var result = [];
c(array.sort(function (a, b) { return b - a; }), [], sum);
return result;
}
console.log(combine([2, 5, 7], 6));
console.log(combine([1, 5, 7], 6));
console.log(combine([1, 2, 4, 8, 16, 32, 64, 128, 256, 512], 3497));
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
答案 1 :(得分:2)
这是一些正确查找任何集合中的加数的递归代码:
function summands(n, values) {
function s(n, found, values) {
if (!n)
return found;
let t;
values
.filter(x => x <= n)
.some((x, i) => t = s(n - x, found.concat(x), values.slice(i)));
return t;
}
return s(n, [], values.sort((a, b) => b - a));
}
console.log(summands(6, [2, 5, 7]));
console.log(summands(6, [1, 5, 7]));
console.log(summands(3497, [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]));
这是一个产生所有可能组合的生成器:
function *summands(n, values) {
function *s(n, found, values) {
if (n == 0)
yield found;
for (let [i, x] of values.entries()) {
if (x <= n)
yield *s(n - x, found.concat(x), values.slice(i));
}
}
yield *s(n, [], values.sort((a, b) => b - a));
}
for(let k of summands(8, [4,3,1])) {
console.log(k.join())
}
最后,如果你的操作数总是2的幂,你可以用更快的方式为给定数字创建一个位组合:
function toBits(n, size) {
var r = new Array(n >> size).fill(1 << size);
while (size--)
if (n & (1 << size))
r.push(1 << size)
return r;
}
console.log(toBits(3497, 9));