Javascript 从数组中获取最接近的数字
我有一个从-1000到+1000的数字,我有一个包含数字的数组。像这样:Javascript 从数组中获取最接近的数字,javascript,arrays,Javascript,Arrays,我有一个从-1000到+1000的数字,我有一个包含数字的数组。像这样: [2, 42, 82, 122, 162, 202, 242, 282, 322, 362] 我想把我得到的数字改成数组中最接近的数字 例如,我得到80作为数字,我希望它得到82在数组上稍微修改一下二进制搜索就可以了。对于小范围,最简单的方法是有一个map数组,例如,使用您的示例,第80个条目中的值为82。对于一个更大、更稀疏的范围,可能需要进行二进制搜索 使用查询语言,您可以在输入号码的两侧查询一定距离的值,然后对结果
[2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
我想把我得到的数字改成数组中最接近的数字
例如,我得到
80
作为数字,我希望它得到82
在数组上稍微修改一下二进制搜索就可以了。对于小范围,最简单的方法是有一个map数组,例如,使用您的示例,第80个条目中的值为82。对于一个更大、更稀疏的范围,可能需要进行二进制搜索
使用查询语言,您可以在输入号码的两侧查询一定距离的值,然后对结果的缩减列表进行排序。但是SQL没有“下一步”或“上一步”的好概念,无法为您提供“干净”的解决方案。以下是伪代码,可以转换为任何过程语言:
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
作为概念证明,下面是我用来展示这一点的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)
<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>
正如上面所述,对于小数据集或不需要盲目快速的事物,这不应该有很大区别,但这是一个你可能需要考虑的选项。
< P>工作代码如下:var数组=[2,42,82,122,162,202,242,282,322,362];
函数最近(数组,num){
var i=0;
var-minDiff=1000;
var ans;
for(数组中的i){
var m=Math.abs(num-array[i]);
if(mES5版本:
var计数=[4,9,15,6,2],
目标=5;
var最近=计数。减少(功能(上一个,当前){
返回(Math.abs(curr-goal) 控制台日志(最近)代码>我不知道我是否应该回答一个老问题,但由于这篇文章首先出现在谷歌搜索上,我希望您能原谅我在这里添加我的解决方案&2c
由于懒惰,我不敢相信这个问题的解决方案会是一个循环,所以我搜索了更多,并返回了:
就这些 对于排序数组(线性搜索)
到目前为止,所有的答案都集中在搜索整个数组。
考虑到您的数组已经排序,并且您确实只需要最接近的数字,这可能是最快的解决方案:
var a=[2,42,82,122,162,202,242,282,322,362];
var目标=90000;
/**
*返回排序数组中最接近的数字。
**/
功能最近(arr,目标){
如果(!(arr)| arr.length==0)
返回null;
如果(arr.length==1)
返回arr[0];
对于(变量i=1;i目标){
var p=arr[i-1];
var c=arr[i]
返回Math.abs(p-target) 日志(最近的(a,目标))代码>我对一个类似问题的回答是,也考虑了关系,它是纯Javascript,尽管它不使用二进制搜索,所以它是O(N)而不是O(logN):
var searchArray=[0,30,60,90];
var元素=33;
函数findClosest(数组,元素){
var minDelta=null;
var minIndex=null;
对于(var i=0;iES6(ECMAScript 2015)版本:
const counts=[4,9,15,6,2];
常数目标=5;
const output=counts.reduce((当前,当前)=>Math.abs(当前目标) console.log(output);
我喜欢Fusion的方法,但其中有一个小错误。就像这样,它是正确的:
function closest(array, number) {
var num = 0;
for (var i = array.length - 1; i >= 0; i--) {
if(Math.abs(number - array[i]) < Math.abs(number - array[num])){
num = i;
}
}
return array[num];
}
我用console.time()
测试了它,它比其他函数稍快。适用于未排序的数组
虽然这里发布了一些很好的解决方案,但JavaScript是一种灵活的语言,它为我们提供了以多种不同方式解决问题的工具。
当然,这一切都取决于你的风格。如果你的代码功能更强大,你会找到合适的代码,即:
arr.reduce(function (prev, curr) {
return (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);
});
与使用Math.min.apply
查找最小值相反,此函数不需要对输入数组arr
进行排序。我们不需要关心索引或事先对其进行排序。
为了清楚起见,我将逐行解释代码:
arr.map(函数(k){return Math.abs(k-x)})
创建一个新数组,基本上存储给定数字的绝对值(arrarr
中的数字)减去输入数字(x
)。接下来我们将查找最小的数字(也是最接近输入数字的)
Math.min.apply(Math,indexArr)
这是在我们刚刚创建的数组中查找最小数的合法方法(仅此而已)
arr[indexArr.indexOf(min)]
这可能是最有趣的部分。我们已经找到了最小的数字,但我们不确定是否应该加上或减去初始数字(x
)。这是因为我们使用了Math.abs()
来找到差异。然而,array.map
创建了(逻辑上的)输入数组的映射,使索引保持在同一位置。因此,要找到最接近的数字,我们只需返回给定数组中找到的最小值的索引indexArr.indexOf(min)
我已经创建了一个演示程序。此解决方案使用ES5,如果满足条件,它允许停止迭代
相反,它不需要为一个结果迭代所有元素
在回调内部,获取搜索值和实际项
之间的绝对增量
,并与上一个增量进行比较。如果大于或等于,则迭代停止,因为所有其他值及其增量都大于实际值
如果c中的delta
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
var myArray = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];
var myValue = 80;
function BiggerThan(inArray) {
return inArray > myValue;
}
var arrBiggerElements = myArray.filter(BiggerThan);
var nextElement = Math.min.apply(null, arrBiggerElements);
alert(nextElement);
var searchArray= [0, 30, 60, 90];
var element= 33;
function findClosest(array,elem){
var minDelta = null;
var minIndex = null;
for (var i = 0 ; i<array.length; i++){
var delta = Math.abs(array[i]-elem);
if (minDelta == null || delta < minDelta){
minDelta = delta;
minIndex = i;
}
//if it is a tie return an array of both values
else if (delta == minDelta) {
return [array[minIndex],array[i]];
}//if it has already found the closest value
else {
return array[i-1];
}
}
return array[minIndex];
}
var closest = findClosest(searchArray,element);
function closest(array, number) {
var num = 0;
for (var i = array.length - 1; i >= 0; i--) {
if(Math.abs(number - array[i]) < Math.abs(number - array[num])){
num = i;
}
}
return array[num];
}
var getClosest = function(number, array) {
var current = array[0];
var difference = Math.abs(number - current);
var index = array.length;
while (index--) {
var newDifference = Math.abs(number - array[index]);
if (newDifference < difference) {
difference = newDifference;
current = array[index];
}
}
return current;
};
arr.reduce(function (prev, curr) {
return (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);
});
var findClosest = function (x, arr) {
var indexArr = arr.map(function(k) { return Math.abs(k - x) })
var min = Math.min.apply(Math, indexArr)
return arr[indexArr.indexOf(min)]
}
findClosest(80, [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]) // Outputs 82
if (delta >= lastDelta) {
if (delta > lastDelta) {
// ^^^ without equal sign
function closestNumberInCircularRange(codes, charCode) {
return codes.reduce((p_code, c_code)=>{
if(((Math.abs(p_code-charCode) > Math.abs(c_code-charCode)) || p_code > charCode) && c_code < charCode){
return c_code;
}else if(p_code < charCode){
return p_code;
}else if(p_code > charCode && c_code > charCode){
return Math.max.apply(Math, [p_code, c_code]);
}
return p_code;
});
}
package com.algo.closestnumberinarray;
import java.util.TreeMap;
public class Find_Closest_Number_In_Array {
public static void main(String arsg[]) {
int array[] = { 1, 60, 0, -10, 100, 87, 69 };
int number = 56;
int num = getClosestNumber(array, number);
System.out.println("Number is=" + num);
}
public static int getClosestNumber(int[] array, int number) {
int diff[] = new int[array.length];
TreeMap<Integer, Integer> keyVal = new TreeMap<Integer, Integer>();
for (int i = 0; i < array.length; i++) {
if (array[i] > number) {
diff[i] = array[i] - number;
keyVal.put(diff[i], array[i]);
} else {
diff[i] = number - array[i];
keyVal.put(diff[i], array[i]);
}
}
int closestKey = keyVal.firstKey();
int closestVal = keyVal.get(closestKey);
return closestVal;
}
}
const needle = 5;
const haystack = [1, 2, 3, 4, 5, 6, 7, 8, 9];
haystack.sort((a, b) => {
return Math.abs(a - needle) - Math.abs(b - needle);
})[0];
// 5
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
class CompareFunctor
{
public:
CompareFunctor(int n) { _n = n; }
bool operator()(int & val1, int & val2)
{
int diff1 = abs(val1 - _n);
int diff2 = abs(val2 - _n);
return (diff1 < diff2);
}
private:
int _n;
};
int Find_Closest_Value(int nums[], int size, int n)
{
CompareFunctor cf(n);
int cn = *min_element(nums, nums + size, cf);
return cn;
}
int main()
{
int nums[] = { 2, 42, 82, 122, 162, 202, 242, 282, 322, 362 };
int size = sizeof(nums) / sizeof(int);
int n = 80;
int cn = Find_Closest_Value(nums, size, n);
cout << "\nClosest value = " << cn << endl;
cin.get();
}
function findTwoClosest(givenList, goal) {
var first;
var second;
var finalCollection = [givenList[0], givenList[1]];
givenList.forEach((item, firtIndex) => {
first = item;
for (let i = firtIndex + 1; i < givenList.length; i++) {
second = givenList[i];
if (first + second < goal) {
if (first + second > finalCollection[0] + finalCollection[1]) {
finalCollection = [first, second];
}
}
}
});
return finalCollection;
}
var counts = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
var goal = 80;
console.log(findTwoClosest(counts, goal));
function findClosestIndex(arr, element) {
let from = 0, until = arr.length - 1
while (true) {
const cursor = Math.floor((from + until) / 2);
if (cursor === from) {
const diff1 = element - arr[from];
const diff2 = arr[until] - element;
return diff1 <= diff2 ? from : until;
}
const found = arr[cursor];
if (found === element) return cursor;
if (found > element) {
until = cursor;
} else if (found < element) {
from = cursor;
}
}
}
console.log(findClosestIndex([0, 1, 2, 3.5, 4.5, 5], 4));
// output: 3
console.log(findClosestIndex([0, 1, 2, 3.49, 4.5, 5], 4));
// output: 4
console.log(findClosestIndex([0, 1, 2, 3.49, 4.5, 5], 90));
// output: 5
console.log(findClosestIndex([0, 1, 2, 3.49, 4.5, 5], -1));
// output: 0