【问题标题】:binarySearch to find closest number to target . undefined as return valuebinarySearch 找到最接近目标的数字。未定义为返回值
【发布时间】:2018-02-19 23:51:26
【问题描述】:

我正在研究一个函数,该函数应该从整数列表中将最接近的较低数字返回给目标。 (即 [1,23,45,67,94,122],目标 = 96。应该返回 94)。我已经多次查看我的代码,试图“捕获导致该函数返回“未定义”的错误,但我无法找出原因......当我通过该过程打印出我的变量时,它们都匹配我想要什么,但我的返回值一直是未定义的。我在想我的问题在于前两个条件,但我仍然不知道为什么。有什么线索吗?

这是我的代码:

function binarySearch(arr,target){
  var midpoint = Math.floor(arr.length/2);

  if (arr[midpoint] === target){
    return arr[midpoint];
  }
  if (arr.length === 1){
    return arr[0];
  }

  if (arr[midpoint] > target){
    binarySearch(arr.slice(0,midpoint),target);
  }else if (arr[midpoint] < target){
    binarySearch(arr.slice(midpoint),target);
  }
}

binarySearch([1,23,45,67,94,122],96); => 预期返回值 = 94 // 得到 = 未定义。 :/

【问题讨论】:

  • 因为你没有在递归中返回
  • 请注意,最后的if(在else 之后)是多余的。您已经检查了equalsgreater than 案例。
  • 作为 Disha Umarwani points out,这会计算出与最接近的值不同的值:不大于目标的最大值。例如,如果你使用上面的目标92,你会得到67的值,如果这是你想要的,很好,但如果不是,你可以看看stackoverflow.com/a/30245398/1243641

标签: javascript undefined binary-search


【解决方案1】:

执行递归调用时需要添加return语句

 function binarySearch(arr,target){
  var midpoint = Math.floor(arr.length/2);

  if (arr[midpoint] === target){
    return arr[midpoint];
  }
  if (arr.length === 1){
    return arr[0];
  }

  if (arr[midpoint] > target){
    return binarySearch(arr.slice(0,midpoint),target);
  }else if (arr[midpoint] < target){
    return binarySearch(arr.slice(midpoint),target);
  }
}

【讨论】:

  • 对!!!我认为前两个条件中的返回值足以让它作为“全局返回值”工作。谢谢!!!
【解决方案2】:

所以原来的算法似乎是错误的,选择小于目标的最大值,而不是数值上最接近它的那个。

这是另一个受a java version 启发的版本,但它是为 ES6 编写的,并且像问题的代码一样是递归的。

function binarySearch(arr, target, lo = 0, hi = arr.length - 1) {
   if (target < arr[lo]) {return arr[0]}
   if (target > arr[hi]) {return arr[hi]}
   
   const mid = Math.floor((hi + lo) / 2);

   return hi - lo < 2 
     ? (target - arr[lo]) < (arr[hi] - target) ? arr[lo] : arr[hi]
     : target < arr[mid]
       ? binarySearch(arr, target, lo, mid)
       : target > arr[mid] 
         ? binarySearch(arr, target, mid, hi)
         : arr[mid]
}

console.log(binarySearch([1, 23, 45, 67, 94, 122], 96))  //=> 94
console.log(binarySearch([1, 23, 45, 67, 94, 122], 47))  //=> 45
console.log(binarySearch([1, 23, 45, 67, 94, 122], 207)) //=> 122
console.log(binarySearch([1, 23, 45, 67, 94, 122], 0))   //=> 1

【讨论】:

    【解决方案3】:

    我认为您的算法不会给出正确的结果。 您需要首先找到应该插入元素的位置。 这是堆栈溢出链接: O(log n) algorithm to find best insert position in sorted array

      function binarySearch(arr,target, l, h){
      var midpoint = Math.floor(l+h/2);
    
      if (arr[midpoint] === target){
        return midpoint;
      }
      if (l === h){
        return l;
      }
    
      if (arr[midpoint] > target){
        return binarySearch(arr,target, l,midpoint);
      }else if (arr[midpoint] < target){
        return binarySearch(arr, target, midpoint,h);
      }
    }
     function binaryclosest(arr, i){
     x= abs(target - arr[i]) 
     y = arr[i+1] - target
     z = target - arr[i-1]
     if(x<y && x<z){
         return arr[i]
     }
     else{
         if(y<z)
            return arr[i+1]
         else
            return arr[i-1]
     }
    }
    i = binarySearch(arr, target, l, h) 
    value = binaryclosest(arr, i)
    

    然后,你应该减去 i-1 和 i+1 取一个 mod 然后返回较低的那个

    【讨论】:

    • OP 只要求最接近的值,而不是插入点。除了缺少returns,原代码看起来是对的,虽然我没有测试过。
    • 那么,为什么 OP 假设 a[0] 是最接近的?他可能在遍历数组的另一端时错过了一些东西。
    • 我猜它没有被提及,但我认为列表已排序。如果这是正确的,你能举一个失败的例子吗?也许我很困惑。
    • 哦,等等,你是对的。我很困惑。这会找到不大于目标的最大数字,但不一定是最接近的数字。
    • 我还没有测试我的代码,但逻辑保持不变。但是,我确信我的逻辑是正确的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多