从数组中获取最接近的数字
2022-08-30 00:44:02
我有一个从负1000到加1000的数字,我有一个包含数字的数组。喜欢这个:
[2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
我希望我得到的数字更改为数组的最接近的数字。
例如,我得到的数字,我希望它得到。80
82
我有一个从负1000到加1000的数字,我有一个包含数字的数组。喜欢这个:
[2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
我希望我得到的数字更改为数组的最接近的数字。
例如,我得到的数字,我希望它得到。80
82
ES5 版本:
var counts = [4, 9, 15, 6, 2],
goal = 5;
var closest = counts.reduce(function(prev, curr) {
return (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);
});
console.log(closest);
以下是伪代码,应该可以转换为任何过程语言:
array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
number = 112
print closest (number, array)
def closest (num, arr):
curr = arr[0]
foreach val in arr:
if abs (num - val) < abs (num - curr):
curr = val
return curr
它只是计算出给定数字和每个数组元素之间的绝对差异,并返回其中一个差异最小的元素。
对于示例值:
number = 112 112 112 112 112 112 112 112 112 112
array = 2 42 82 122 162 202 242 282 322 362
diff = 110 70 30 10 50 90 130 170 210 250
|
+-- one with minimal absolute difference.
作为概念证明,以下是我用来演示此操作的Python代码:
def closest (num, arr):
curr = arr[0]
for index in range (len (arr)):
if abs (num - arr[index]) < abs (num - curr):
curr = arr[index]
return curr
array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
number = 112
print closest (number, array)
而且,如果您真的需要Javascript,请参阅下面的完整HTML文件,该文件演示了该函数的实际运行情况:
<html>
<head></head>
<body>
<script language="javascript">
function closest (num, arr) {
var curr = arr[0];
var diff = Math.abs (num - curr);
for (var val = 0; val < arr.length; val++) {
var newdiff = Math.abs (num - arr[val]);
if (newdiff < diff) {
diff = newdiff;
curr = arr[val];
}
}
return curr;
}
array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];
number = 112;
alert (closest (number, array));
</script>
</body>
</html>
现在请记住,如果对数据项进行排序(可以从示例数据中推断出来,但您没有明确说明),则可能存在提高效率的余地。例如,您可以使用二进制搜索来查找最近的项目。
您还应该记住,除非您需要每秒多次这样做,否则除非您的数据集变得更大,否则效率的提高将几乎不明显。
如果你确实想以这种方式尝试(并且可以保证数组按升序排序),这是一个很好的起点:
<html>
<head></head>
<body>
<script language="javascript">
function closest (num, arr) {
var mid;
var lo = 0;
var hi = arr.length - 1;
while (hi - lo > 1) {
mid = Math.floor ((lo + hi) / 2);
if (arr[mid] < num) {
lo = mid;
} else {
hi = mid;
}
}
if (num - arr[lo] <= arr[hi] - num) {
return arr[lo];
}
return arr[hi];
}
array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];
number = 112;
alert (closest (number, array));
</script>
</body>
</html>
它基本上使用括号和中间值检查来减少每次迭代的解空间一半,这是一种经典的算法,而上面的顺序搜索是:O(log N)
O(N)
0 1 2 3 4 5 6 7 8 9 <- indexes
2 42 82 122 162 202 242 282 322 362 <- values
L M H L=0, H=9, M=4, 162 higher, H<-M
L M H L=0, H=4, M=2, 82 lower/equal, L<-M
L M H L=2, H=4, M=3, 122 higher, H<-M
L H L=2, H=3, difference of 1 so exit
^
|
H (122-112=10) is closer than L (112-82=30) so choose H
如前所述,对于小型数据集或不需要快得快的东西来说,这应该不会有太大的区别,但这是您可能需要考虑的一种选择。