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

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

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

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


当前回答

工作代码如下:

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));

其他回答

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

适用于无序数组

虽然这里有一些很好的解决方案,但JavaScript是一种灵活的语言,它为我们提供了以多种不同方式解决问题的工具。 当然,这一切都取决于你的风格。如果你的代码更实用,你会发现减少变化是合适的,即:

  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

与使用Math.min找到最小值的其他方法相反。应用,这个不需要输入数组arr排序。我们不需要关心索引或者事先排序。

为了清晰起见,我将逐行解释代码:

arr.map(function(k) { return Math.abs(k - x) }) Creates a new array, essentially storing the absolute values of the given numbers (number in arr) minus the input number (x). We'll look for the smallest number next (which is also the closest to the input number) Math.min.apply(Math, indexArr) This is a legit way of finding the smallest number in the array we've just created before (nothing more to it) arr[indexArr.indexOf(min)] This is perhaps the most interesting part. We have found our smallest number, but we're not sure if we should add or subtract the initial number (x). That's because we used Math.abs() to find the difference. However, array.map creates (logically) a map of the input array, keeping the indexes in the same place. Therefore, to find out the closest number we just return the index of the found minimum in the given array indexArr.indexOf(min).

我创建了一个箱子来演示它。

如果数组像你的例子中那样排序,你可以使用二进制搜索来获得O(log n)更好的时间复杂度。

const myArray = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]; const binaryClosestIdx = (arr, target) => { let start = 0; let end = arr.length - 1; let mid = Math.floor((start + end) / 2); while (1) { if (arr[mid] === target) { return mid; } else if (start >= end) { break; } else if (arr[mid] > target) { end = mid - 1; } else { start = mid + 1; } mid = Math.floor((start + end) / 2); } // Return the closest between the last value checked and it's surrounding neighbors const first = Math.max(mid - 1, 0); const neighbors = arr.slice(first, mid + 2); const best = neighbors.reduce((b, el) => Math.abs(el - target) < Math.abs(b - target) ? el : b); return first + neighbors.indexOf(best); } const closestValue = myArray[binaryClosestIdx(myArray, 80)]; console.log(closestValue);

工作原理:

它将目标值与数组的中间元素进行比较。如果中间的元素更大,我们可以忽略它后面的每个元素,因为它们会更大。同样,如果中间的元素更小,我们可以忽略它之前的所有元素。 如果找到了目标值,则返回它,否则将最后测试的值与其周围的相邻值进行比较,因为最近的值只能在这3个值之间。

我喜欢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];
    }

它也更快一点,因为它使用了改进的for循环。

最后,我这样写函数:

    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;
    };

我用console.time()测试了它,它比其他函数略快。

ES6

适用于已排序和未排序数组

数字整数和浮点数,字符串欢迎

/**
 * Finds the nearest value in an array of numbers.
 * Example: nearestValue(array, 42)
 * 
 * @param {Array<number>} arr
 * @param {number} val the ideal value for which the nearest or equal should be found
 */
const nearestValue = (arr, val) => arr.reduce((p, n) => (Math.abs(p) > Math.abs(n - val) ? n - val : p), Infinity) + val

例子:

let values = [1,2,3,4,5]
console.log(nearestValue(values, 10)) // --> 5
console.log(nearestValue(values, 0)) // --> 1
console.log(nearestValue(values, 2.5)) // --> 2

values = [100,5,90,56]
console.log(nearestValue(values, 42)) // --> 56

values = ['100','5','90','56']
console.log(nearestValue(values, 42)) // --> 56