Javascript 尝试返回递归组合函数而不获取';未定义';
当我用[1,2,3,4]调用它时,它返回undefined,我不明白为什么。其目标是,如果数组中的任何数字组合加起来等于数组中的最大数字,则返回true;如果不可能,则返回falseJavascript 尝试返回递归组合函数而不获取';未定义';,javascript,for-loop,recursion,combinations,Javascript,For Loop,Recursion,Combinations,当我用[1,2,3,4]调用它时,它返回undefined,我不明白为什么。其目标是,如果数组中的任何数字组合加起来等于数组中的最大数字,则返回true;如果不可能,则返回false function ArrayAdditionI(arr) { var max = Math.max.apply(null, arr); arr.splice(arr.indexOf(max), 1); var sum = function(arr) { return arr.reduce(funct
function ArrayAdditionI(arr) {
var max = Math.max.apply(null, arr);
arr.splice(arr.indexOf(max), 1);
var sum = function(arr) { return arr.reduce(function(a,b) { return a + b; }); };
function combos(arr) {
var f = function(prefix, arr) {
for (var i = 0; i < arr.length; i++) {
var clone = prefix.slice(0);
clone.push(arr[i]);
if (sum(clone) == max) { return true; }
return f(clone, arr.slice(i+1));
}
}
return f([], arr);
}
return combos(arr);
}
函数数组添加(arr){
var max=Math.max.apply(null,arr);
arr.拼接(arr.indexOf(最大值),1);
var sum=函数(arr){返回arr.reduce(函数(a,b){返回a+b;});};
函数组合(arr){
var f=函数(前缀,arr){
对于(变量i=0;i
您似乎没有测试所有可能的组合
在这里,您将测试1+2+3、2+3、3,但永远不会测试1+3
你真的想在这里有一个递归函数吗?
也许有更简单的方法可以找到
function ArrayAdditionI(arr) {
var max = Math.max.apply(null, arr);
arr.splice(arr.indexOf(max), 1);
var res = arr.filter(function(num, idx) {
var combination = false;
// Check all combination non previously tested
for (var i = idx; i < arr.length - 1; i++) {
if (num + arr[i+1] === max) {
combination = true;
break;
}
}
return combination;
});
return res.length > 0;
}
函数数组添加(arr){
var max=Math.max.apply(null,arr);
arr.拼接(arr.indexOf(最大值),1);
var res=arr.filter(函数(num,idx){
var组合=假;
//检查所有未经测试的组合
对于(var i=idx;i0;
}
问题在于您的f
函数从未命中
if(sum(clone)==max){return true;}
代码行,因此它将继续递归调用,直到arr.length==0,并且它将返回undefined
您的变量torf和结果未使用,可能您忘记对它们做些什么了?
f
在使用空的arr
调用时返回未定义的!如果循环中没有任何测试从函数返回,则需要显式地返回false
。并且,您不能在循环的第一次返回false
,而只能在找到true
时中断,然后继续循环
要解决这个问题,你需要
function combos(arr) {
function f(prefix, arr) {
for (var i = 0; i < arr.length; i++) {
var clone = prefix.slice(0);
clone.push(arr[i]);
if (sum(clone) == max) return true;
if (f(clone, arr.slice(i+1))) return true;
}
return false;
}
return f([], arr);
}
不,它们只是剩下的。那么解决办法是什么?我试图打破for循环,但也没有成功。我猜如果第一组调用arr.length==0返回undefined,那么for应该在带有[1]的数组上继续使用I=1,但是我不知道如何做,但是您的代码只是测试数组中2个项的组合,而不是所有可能的项?嘿,Bergi,这看起来很棒,但是当我尝试第二个时(在reduce函数上添加起始值后)我得到了超过最大调用堆栈大小的结果。我不明白为什么第一个代码块或原始设计“有缺陷”。感谢您精彩的解释。当arr
为空时,它必须停止递归。现在已修复。好的,您的递归尝试将实际起作用。我对循环感到非常困惑,最初认为它将枚举一些“前缀”(实际上是子集)多次,甚至跳过它们。但是,在仔细考虑之后,它甚至可能比简单枚举二叉树或所有可能的子集的朴素解决方案受益,并且递归调用更少。这是一个漂亮的函数:')!(顺便说一句,我认为array.length
应该是arr.length
?)
function ArrayAdditionI(arr) {
var max = Math.max.apply(null, arr);
arr.splice(arr.indexOf(max), 1);
var sum = function(arr) { return arr.reduce(function(a,b) { return a + b; }, 0); };
function f(subset, arr) {
return arr.length
? f(subset, arr.slice(1)) || f(subset.concat([arr[0]]), arr.slice(1))
: sum(subset) == max
}
return f([], arr);
}