我有一个从- 1000到+ 1000的数我有一个数组,里面都是数字。是这样的:

[2, 42, 82, 122, 162, 202, 242, 282, 322, 362]

我想让我得到的数字变成数组中最接近的数字。

例如,我的数字是80,我希望它是82。


当前回答

#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();
}

其他回答

ES5版本:

Var计数= [4,9,15,6,2], 目标= 5; Var最接近=计数。Reduce(函数(prev, curr) { 返回(数学。abs(curr - goal) <数学。腹肌(前一球)?Curr: prev); }); console.log(最近的);

最有效的方法是二分查找。然而,即使是简单的解决方案,当下一个数字与当前数字进一步匹配时,也可以退出。这里几乎所有的解决方案都没有考虑到数组是有序的,并且迭代整个:/

const closest = (orderedArray, value, valueGetter = item => item) => orderedArray.find((item, i) => i === orderedArray.length - 1 || Math.abs(value - valueGetter(item)) < Math.abs(value - valueGetter(orderedArray[i + 1]))); var data = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]; console.log('21 -> 2', closest(data, 21) === 2); console.log('22 -> 42', closest(data, 22) === 42); // equidistant between 2 and 42, select highest console.log('23 -> 42', closest(data, 23) === 42); console.log('80 -> 82', closest(data, 80) === 82);

这也可以在非原语上运行,例如,nearest (data, 21, item => item.age)

将find更改为findIndex以返回数组中的索引。

其他答案建议你需要遍历整个数组:

计算每个元素的偏差 跟踪最小偏差及其元素 最后,在遍历整个数组后,返回具有最小偏差的元素。

如果数组已经排序了,那就没有意义了。没有必要计算所有的偏差。例如,在一个100万个元素的有序集合中,你只需要计算~19个偏差(最多)来找到你的匹配。你可以用二进制搜索方法来实现:

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

对于一个较小的范围,最简单的方法是有一个map数组,例如,用你的例子来说,第80个条目的值是82。对于一个更大、更稀疏的范围,可能的方法是二分搜索。

使用查询语言,您可以查询与输入数字任意一侧有一定距离的值,然后对结果减少的列表进行排序。但是SQL并没有一个“下一个”或“上一个”的好概念,来给你一个“干净”的解决方案。

工作代码如下:

var 数组 = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]; 函数 closest(array, num) { 煮沸i = 0; var minDiff = 1000; 变量; 对于(数组中的 i){ var m = Math.abs(num - array[i]); if (m < minDiff) { 最小差异 = m; ans = 数组[i]; } } 返回和; } 控制台.log(最接近(阵列,88));