如何使用Javascript将数组中最接近的重复值转换为目标值?

时间:2017-06-03 00:09:10

标签: javascript arrays algorithm

// Shorthand for $( document ).ready()
$(function() {
  var SwitchesByNumberOfPorts = [48,24];
  var Target = 115;
  var Target_Copy = Target;
  var needSwitches = [];

  SwitchesByNumberOfPorts.forEach(function(ports) {
    while(Target_Copy >= ports) {
      Target_Copy -= ports;
      needSwitches.push(ports);
    }
  });

  var portsCalculated = needSwitches.reduce((a, b) => a + b, 0);

  if (portsCalculated<Target){
    var RemainingTarget = Target - portsCalculated;
    var AdditionalPorts = SwitchesByNumberOfPorts.reduce(function (prev, curr) {
    return (Math.abs(curr - RemainingTarget) < Math.abs(prev - RemainingTarget) ? curr : prev);
    });
    needSwitches.push(AdditionalPorts)
  }
	$("#result").html(needSwitches.join(", "));
	//console.log(needSwitches);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result">Loading...</div>

该查询涉及JavaScript计算,以根据客户提供的端口数归档所需的网络交换机数量。

可用的网络交换机是:每个单元24和48个端口。

例如,如果客户端目前有115个端口,则提供的最佳解决方案是2个48端口交换机和1个24端口交换机,剩余5个端口可用。

我正在寻找JavaScript中的算法或函数,这将允许我添加一个值数组[24,48]并获得最接近目标115的结果。

var SwitchesByNumberOfPorts = [24,48]
var Target = 115
getClosestArrayValues(SwitchesByNumberOfPorts , Target)

// Expected Result  [48,48,24] #120 ports

2 个答案:

答案 0 :(得分:2)

你可以用筛子。如有必要,将输入值从大到小排序,并创建一个空筛:

{0:[]}

然后对于输入中的每个值,迭代筛子中的值(包括您刚刚在此步骤中添加的值)并将值添加到它们,直到您到达或通过目标。在这个例子中,我们从48开始:

{0:[], 48:[48], 96:[48,48], 144:[48,48,48]}

对下一个值24执行相同操作:

{0:[], 24:[24], 48:[48], 72:[48,24], 96:[48,48], 120:[48,48,24], 144:[48,48,48]}

当您创建的新值时,例如24 + 24 = 48,已经存在,不要替换它,以便使用最小数量的值,即48而不是24 + 24,48 + 24而不是24 + 24 + 24等...... / p>

当您查看所有值时,请将筛子中的第一个项目等于或大于目标。在示例中,即:

120:[48,48,24]

对于示例输入[30,20,15]和目标35,将是:

{0:[]}
{0:[], 30:[30], 60:[30,30]}
{0:[], 20:[20], 30:[30], 40:[20,20], 60:[30,30]}
{0:[], 15:[15], 20:[20], 30:[30], 35:[20,15], 40:[20,20], 60:[30,30]}

结果是:

35:[20,15]

注意:如果您偏好使用从高到低的值,则只需在创建筛子之前按优先顺序对值进行排序;例如使用[20,15,30]将导致65:[20,15,15,15]而不是65:[30,20,15]。

答案 1 :(得分:0)

  1. 从高到低排序
  2. sorted = vals.sort((a,b) => b>a)

    1. 对于每个元素,从目标值中减去,直到您不能再继续,并跟踪
    2. sorted.forEach(v => { while(target_copy >= v) { target_copy -= v needs.push(v) } })

      1. 然而,这将使最后一次购买需要关闭,所以最后,检查您是否需要再购买最小的一次

        if(target_copy&gt; 0){needs.push(sorted [sorted.length -1])}

      2. 这是一个js控制台,显示它在行动:

        function seek (set, target) {
         let needs = []
         let sorted = set.sort((a,b) => b>a)
         sorted.forEach(v => {
           while(target >= v) {
             target -= v
             needs.push(v)
           }
         })
         if(target > 0) { needs.push(sorted[sorted.length - 1]) }
         return needs
        }
        undefined
        seek([48,24],115)
        (3) [48, 48, 24]