使用数字数组来累加特定数字

时间:2018-03-13 11:36:18

标签: javascript jquery recursion sum calculation

我一直试图找到一种从数组中找到多个数字的有效方法,这些数字加起来给定的数字。在这种情况下,我试图找到总数为目标数的3个数字。

我在下面有一个基本的工作示例,但不幸的是递归循环失败,看起来它有一个问题,它不断循环。理想情况下,它会找到第一个可能的答案并将其返回,但是当它无法找到答案时,它会陷入循环并打破浏览器。

警告:由于内存泄漏,以下代码将中断:

let array = [5,6,3,3,6,67,2,2,6,7,7,2,1,3,4,5,67,7,4,2,5,6,3,3,6,67,2,2,6,7,7,2,1,3,4,5,67,7,4,2,5,6,3,3,6,67,2,2,6,7,7,2,1,3,4,5,67,7,4,2];

function findSums(arr, target, count) {
    var result = [];
    function recurse(start, leftOver, selection) {
        if (leftOver < 0) return; // failure
        if (leftOver === 0 && selection.length == count) {
            result.push(selection); // add solution
            return;
        }
        for (var i = start; i < arr.length; i++) {
            recurse(i, leftOver-arr[i], selection.concat(arr[i]));
        }
    }
    recurse(0, target, []);
    return result;
}
// Demo
$('#input').on('blur', function(e){
  let value = parseInt(e.target.value);
  let result = findSums(array, value, 3);
  if(result.length > 0){
    $('#output').text(result[0]); 
  } else {
    $('#output').text('Nothing found');
  }
  
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Input Number Below</h1>
<input id="input" type="number" />
<code id="output" ></code>

1 个答案:

答案 0 :(得分:1)

嗯,当我测试时,它没有破坏,但仍然有一些提示:

您应该为计数设置其他限制。你正在拨打额外的电话。当你的函数处理真正的大数,小数和小数时,它将再次调用自身,直到它达到或溢出所需的总和,并且只有在它之后才会检查当前计数。所以你应该添加

if (selection.length > count) return;

另外。正如我所看到的,你的数组中有许多重复,所以我认为,允许使用相同的数字,但前提是它取自另一个索引。在循环中,您使用相同的起始索引调用下一个recurse。我想,你需要

for (var i = start; i < arr.length; i++) {
    recurse(i + 1, leftOver-arr[i], selection.concat(arr[i]));
}

最后。这不会影响算法的递归部分,但您可能希望过滤掉相同的结果,或过滤掉您的数组以删除所有重复项。

希望这有帮助。

编辑:抱歉,错过了关于第一个可能解决方案的部分。以下是实现此目的的方法:

function recurse(start, leftOver, selection) {
  if (leftOver < 0) return false; // failure
  if (selection.length > count) return false;
  if (leftOver === 0 && selection.length == count) {
      result.push(selection); // add solution
      return true;
  }
  for (var i = start; i < arr.length; i++) {
      var res = recurse(i + 1, leftOver-arr[i], selection.concat(arr[i]));
      if (res) return true;
  }
}