簡體   English   中英

二分搜索以找到最接近目標數字的浮點值

[英]binary Search to find closest float value to target number

我有一些問題,也許你們中的一個可以幫助我,我有一個浮點數組,但我找不到與目標數字最接近的浮點值(浮點數)

我使用帶有 javascript 的簡單二進制搜索從這里我卡住了。

function binarySearch(arr, val, start = 0, end = arr.length - 1) {
    const mid = Math.floor((start + end) / 2);

    if(Math.abs(val - arr[mid]) < Math.abs(val - arr[mid + 1])){
        return mid;
    }

    if (start >= end) {
        return -1;
    }

    return val < arr[mid]
        ? binarySearch(arr, val, start, mid - 1)
        : binarySearch(arr, val, mid + 1, end);
}
let array = [0,0.03336667683886884,0.06673335367773768,0.10010003051660653,0.13346670735547536,0.1668333841943442,0.20020006103321306]

let result = binarySearch(array,'0.166833') //=> This value needs to be returned 0.1668333841943442

你的條件Math.abs(val - arr[mid]) < Math.abs(val - arr[mid + 1])是錯誤的,你總是檢查左邊的值比右邊的值更接近,所以即使是值 1數組 [10, 20, 30, 40],當您檢查數字 20 時,1 更接近 20 而不是 30 - 然后返回不正確的結果。

此外,您需要檢查邊緣情況,索引mid + 1可能不可用。 此外,該值可能小於最小值或大於最大值,因此可能會出現無限循環。

讓我為您提供這個解決方案:

function binarySearch(arr, val, start, end) {
    // edge case: value of smaller than min or larger than max
    if(array[0] >= val) return 0;
    if(array[array.length - 1] <= val) return array.length - 1;
    
    while (start <= end) {
        let mid = Math.floor((end + start) / 2);
        
        // value is in interval from previous to current element
        if(val >= arr[mid - 1] && val <= arr[mid]) {
            return Math.abs(val - arr[mid - 1]) < Math.abs(val - arr[mid]) ? mid - 1 : mid;
        }
        else {
            if(arr[mid] < val) {
                start = mid + 1;
            } 
            else {
                end = mid - 1;
            }
        }
    }
    return -1;
}

您的停止條件已損壞。 在您的示例中,如果您提供以下數組:

[0.3, 0.5, 0.8, 2.0]

你在開始時:

  • arr[mid] = 0.5
  • arr[mid + 1] = 0.8

因此,如果您將val = 0.1給您的算法,您將擁有:

  • Math.abs(val - arr[mid]) = 0.4
  • Math.abs(val - arr[mid + 1]) = 0.7

因此,您將返回0.5的索引,盡管您期望的是0.3的索引。

解決您的問題的偽想法是:

if array contains 1 element => return element
else if array contains 2 elements => return element closest to val.
else if val < array[mid] => recurse on first half
else if val > array[mid] => recurse on second half

看起來你有一個錯字。 您不應該返回mid索引,而是從array[mid]返回數組項:

 function binarySearch(arr, val, start = 0, end = arr.length - 1) { const mid = Math.floor((start + end) / 2); if(Math.abs(val - arr[mid]) < Math.abs(val - arr[mid + 1])){ return arr[mid]; } if (start >= end) { return -1; } return val < arr[mid] ? binarySearch(arr, val, start, mid - 1) : binarySearch(arr, val, mid + 1, end); } let array = [0, 0.03336667683886884, 0.06673335367773768, 0.10010003051660653, 0.13346670735547536, 0.1668333841943442, 0.20020006103321306]; console.log(binarySearch(array,'0.166833')) // 0.1668333841943442

我找到了這個解決方案,但我需要返回正確值的索引

 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] } let array = [0, 0.03336667683886884, 0.06673335367773768, 0.10010003051660653,0.13346670735547536, 0.1668333841943442, 0.20020006103321306,30.01]; console.log(binarySearch(array,0.03336))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM