[英]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.