查找给定数字的最接近的数字总和

时间:2016-04-01 11:04:51

标签: javascript php

说我有一个清单[1,2,3,4,5,6,7] 我想找到给定数字的最接近的数字总和。很抱歉这个糟糕的解释,但这是一个例子:

说我有一个清单[1,2,3,4,5,6,7]我想找到最接近的数字,比方说,10。

然后该方法应该返回6和4或7和3,因为它最接近他可以得到10.所以5 + 4是错误的,因为那是9,他可以得到10。

另一个例子:你想要最接近14,所以他应该返回7和6

如果你有任何问题,请问因为很难解释我想要的东西:P

5 个答案:

答案 0 :(得分:1)

 var data= [1, 2, 3,4,5,6,7];
  var closest = 14;
 for (var x = 0; x < data.length; x++) {
    for (var y = x+1; y < data.length; y++) {
             if(data[x] + data[y] == closet){
                     alert(data[x].toString() + "  " + data[y].toString());
                }
            }
       }

答案 1 :(得分:1)

根据我对你的问题的理解,我制作了这个片段。我以为你不想两次使用相同的数字(例如14 =&gt; 7 + 7)。

它正在使用您的示例。

var arr = [1, 2, 3, 4, 5, 6, 7];

var a = 0, b = 0;
var nb = 14;

for(var i in arr) {
  for(var j in arr) {
    if(i != j) {
      var tmp = arr[i] + arr[j];
      if(tmp <= nb && tmp > a + b) {
        a = arr[i];
        b = arr[j];
      }
    }
  }
}

document.write("Closest to " + nb + " => " + a + " + " + b);

答案 2 :(得分:1)

我对这个问题有一点冗长的解决方案,所以更容易看到做了什么。

以下解决方案的主要好处:

  • 第二个循环不会再次从数组的开头开始。我的意思是,不是像往常那样将第二个循环的loop_boundary设置为0,而是从下一个索引开始。如果您的数字数组很长,这会有所帮助。但是,如果它与示例一样短,则对性能的影响很小。将第一个循环的边界减少一个将防止错误发生。
  • 即使所需数字为1或负数,也能正常工作。

小提琴:

JSFiddle

代码:

var numbers = [1,2,3,4,5,6,7];
var wanted_number = 1;
var closest_range, closest1, closest2 = null;

var loop1_boundary = numbers.length-1;
for(var i=0; i<loop1_boundary; i++) {

    var start_index = i+1;
    var loop2_boundary = numbers.length;

    for(var k=start_index; k<loop2_boundary; k++) {

        var number1 = parseInt(numbers[i]);
        var number2 = parseInt(numbers[k]);

        var sum = number1 + number2;
        var range = wanted_number - sum;

        document.write( number1+' + '+number2 +' < '+closest_range+'<br/>' );

        if(Math.abs(range) < Math.abs(closest_range) || closest_range == null ) {
            closest_range = range;
            closest1 = number1;
            closest2 = number2;
        }

    }

    if(range==0){
        break;
    }
}

document.write( 'closest to given number was '+closest1+' and '+closest2+'. The range from wanted number is '+closest_range );

答案 3 :(得分:1)

此提案生成所有可能的组合,将它们收集在一个以和为关键字的对象中,然后过滤最接近给定值的和。

&#13;
&#13;
function getSum(array, sum) {
    function add(a, b) { return a + b; }

    function c(left, right) {
        var s = right.reduce(add, 0);
        if (s > sum) {
            return;
        }
        if (!result.length || s === result[0].reduce(add, 0)) {
            result.push(right);
        } else if (s > result[0].reduce(add, 0)) {
            result = [right];
        }
        left.forEach(function (a, i) {
            var x = left.slice();
            x.splice(i);
            c(left.slice(0, i), [a].concat(right));
        });
    }

    var result = [];
    c(array, [], 0);
    return result;
}

function print(o) {
    document.write('<pre>' + JSON.stringify(o, 0, 4) + '</pre>');
}

print(getSum([1, 2, 3, 4, 5, 6, 7], 10));
print(getSum([1, 2, 3, 4, 5, 6, 7], 14));
print(getSum([1, 2, 3, 4, 5, 6, 7], 19));
&#13;
&#13;
&#13;

答案 4 :(得分:1)

combinelocationOf的函数取自不同作者的不同答案。

&#13;
&#13;
printClosest([0.5,2,4] , 5);
printClosest([1, 2, 3, 4, 5, 6, 7], 28);
printClosest([1, 2, 3, 4, 5, 6, 7], 10.9);
printClosest([1, 2, 3, 4, 5, 6, 7], 10, 2);
printClosest([1, 2, 3, 4, 5, 6, 7], 10, 3);
printClosest([1, 2, 3, 4, 5, 6, 7], 14, 2);

function printClosest(array, value, limit) {
  var checkLength = function(array) {
    return array.length === limit;
  };
  var combinations = combine(array); //get all combinations
  combinations = limit ? combinations.filter(checkLength) : combinations;//limit length if required
  var sum = combinations.map(function(c) { //create an array with sum of combinations
    return c.reduce(function(p, c) {
      return p + c;
    }, 0)
  });
  var sumSorted = sum.slice(0).sort(function(a, b) {//sort sum array
    return a - b;
  });

  index = locationOf(value, sumSorted);//find where the value fits in
  //index = (Math.abs(value - sum[index]) <= Math.abs(value - sum[index + 1])) ? index : index + 1;
  index = index >= sum.length ? sum.length - 1 : index;
  index = sum.indexOf(sumSorted[index]);//get the respective combination

  console.log(sum, combinations, index);

  document.getElementById("result").innerHTML += "value : " + value + " combi: " + combinations[index].toString() + " (limit : " + (limit || "none") + ")<br>";
}


function combine(a) {
  var fn = function(n, src, got, all) {
    if (n == 0) {
      if (got.length > 0) {
        all[all.length] = got;
      }
      return;
    }
    for (var j = 0; j < src.length; j++) {
      fn(n - 1, src.slice(j + 1), got.concat([src[j]]), all);
    }
    return;
  }
  var all = [];
  for (var i = 0; i < a.length; i++) {
    fn(i, a, [], all);
  }
  all.push(a);
  return all;
}

function locationOf(element, array, start, end) {
  start = start || 0;
  end = end || array.length;
  var pivot = parseInt(start + (end - start) / 2, 10);
  if (end - start <= 1 || array[pivot] === element) return pivot;
  if (array[pivot] < element) {
    return locationOf(element, array, pivot, end);
  } else {
    return locationOf(element, array, start, pivot);
  }
}
&#13;
<pre id="result"><pre>
&#13;
&#13;
&#13;