Найдите число в массиве, которое ближе всего к данному - PullRequest
18 голосов
/ 27 января 2011

У меня есть массив целых чисел в JavaScript, [5,10,15,20,25,30,35] когда мне дано число х, как я могу найти элемент в массиве, который ближе всего к этому числу?

Если число превышает значение, но меньше, чем на полпути к следующему числу, я бы выбрал меньшее значение, если бы оно было на полпути к следующему числу, я бы выбрал большее число.

Например, 7 вернул бы 5, а 8 вернул бы 10. Как я могу это сделать? Любая помощь или советы будут оценены. Я искал и не могу найти решение. Я уверен, что это что-то общее.

Ответы [ 6 ]

26 голосов
/ 16 октября 2015

Вероятно, проще всего сделать сортировку по расстоянию от контрольного значения x, а затем взять первый элемент.

Встроенная функция Array.prototype.sort() может принимать функцию сравнения, которая будет вызываться дляпары значений из массива.Затем нужно просто передать функцию сравнения, которая сравнивает два значения на основе их расстояния от эталонного значения x.

let x = 8;
let array = [5, 10, 15, 20, 25, 30, 35];
let closest = array.sort( (a, b) => Math.abs(x - a) - Math.abs(x - b) )[0];

См. Это простое demo .

16 голосов
/ 27 января 2011
function getClosest(array, target) {
    var tuples = _.map(array, function(val) {
        return [val, Math.abs(val - target)];
    });
    return _.reduce(tuples, function(memo, val) {
        return (memo[1] < val[1]) ? memo : val;
    }, [-1, 999])[0];
}

Если применим функциональный подход, вы можете отобразить набор на кортежи (значение, расстояние), а затем уменьшить этот набор на кортеж с наименьшим расстоянием. Мы возвращаем значение в этом кортеже.

Чтобы объяснить использование _.map. Вы отображаете все значения в вашем массиве на новые значения, и функция будет возвращать массив новых значений. В этом случае массив кортежей.

Чтобы объяснить использование _.reduce. Вы уменьшаете массив до одного значения. Вы передаете в массив и памятку. Памятка - это ваш «счетчик хода», когда вы перемещаетесь по массиву. В этом случае мы проверяем, находится ли текущий кортеж ближе, чем памятка, и, если это так, делаем его памяткой. Затем мы возвращаем записку в конце.

Приведенный выше фрагмент кода опирается на underscore.js для удаления мелочей из функционального стиля javascript

11 голосов
/ 27 января 2011

Ваш список примеров отсортирован. Если это всегда так, тогда бинарный поиск вашего номера. Если вы не нашли точное число, завершите бинарный поиск, проверив два числа вокруг того, где число будет , и верните ближайшее. Будьте осторожны с крайними случаями, когда все числа больше или все меньше целевого числа

Если список не всегда отсортирован, просмотрите список, отслеживая наибольшее число <= целевое число и наименьшее число> = целевое число. Верните тот, который ближе всего к цели.

В любом решении вам нужно решить, какую сторону отдать предпочтение, если, например, вы ищете 2 в [1, 3].

5 голосов
/ 27 января 2011

Создайте временный массив того же размера, что и ваш исходный массив, и заполните его разницей между вашим x и элементом массива.

Например, пусть временный массив будет temp [], а ваш исходный массив будет []:

temp[i]=Math.abs(x-a[i]);

Затем верните пользователю index минимального значения в temp [].

0 голосов
/ 27 октября 2012

Я создал свою собственную функцию, так как не смог найти ни одной, которая бы соответствовала моим требованиям.

    function closest_number(quantities, number, closest_factor)
    {
        if (closest_factor == 'ceil')
        {
            quantities.sort(function(a, b)
                {
                    return a - b
                }
            );

            for (var i = 0; i < quantities.length; i++)
            {
                if (quantities[i] >= number)
                {
                    return quantities[i];
                }

                last_value = quantities[i];
            }

            return last_value;
        }
        else if (closest_factor == 'floor')
        {
            quantities.sort(function(a, b)
                {
                    return a - b
                }
            );

            min_value = quantities[0];

            for (var i = 0; i < quantities.length; i++)
            {
                if (number == quantities[i])
                {
                    return number;
                }
                else if (quantities[i] < number)
                {
                    min_value = quantities[i];
                }
                else if(quantities[i] > number)
                {
                    return min_value;
                }           
            }

            return min_value;
        }
        else
        {
            return false;
        }
    };
0 голосов
/ 27 января 2011

Предполагая, что массив отсортирован, пройдитесь по каждой соседней паре целых чисел в массиве. Для каждой пары (скажем, «5 и 10» или «20 и 25»), проверьте, находится ли между ними x , и, если так, верните, какая из них ближе к x ( с уклоном в сторону нижнего).

Вам также потребуется специальный случай, когда x меньше первого числа (возвращает первое число) или больше последнего числа (возвращает последнее число).

Если массив не отсортирован, сначала выполните его сортировку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...