obter o número mais próximo da matriz


163

Eu tenho um número de menos 1000 a mais 1000 e tenho uma matriz com números. Como isso:

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

Eu quero que o número que eu tenho mude para o número mais próximo da matriz.

Por exemplo, recebo 80o número que quero que ele obtenha 82.


2
Impossivelmente simples: reserve uma variável x, analise a matriz uma a uma, compare icom o número atual na matriz, se a diferença entre ela e ifor menor que o valor atual em x, defina xo número atual da matriz. Quando terminar, xtem o número mais próximo ida matriz.
deceze

Respostas:


208

Versão 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);


1
A desvantagem é que ele só funciona se o retorno de chamada do reduzir for chamado do mesmo escopo que os vars declarados. Como você não pode passar goalpara reduzir, você deve referenciá-lo de um escopo global.
7694r 6/02

5
poderia usar uma função de ordem superior para fazer isso também.
Dmp

3
@ 7yl4r ou envolvê-lo em uma função? ;)
Domingos

1
@ 7yl4r na verdade não ... você pode usar bind para conseguir isso ... ---------- // reducer.js function reducer (goal, prev, curr) {return (Math.abs (curr - meta) <Math.abs (anterior - meta)? curr: anterior); } // main.js var counts = [4, 9, 15, 6, 2], goal = 5; counts.reduce (reducer.bind (null, goal)); ---------- Não sei como colocar código nos comentários hahaha.
Mauricio Soares

Isso itera sobre todos os itens que não são ideais se a lista estiver ordenada, mas ok para pequenas listas. Mesmo sem uma pesquisa binária, um loop pode sair se o próximo número estiver mais longe.
Dominic

144

Aqui está o pseudocódigo que deve ser conversível em qualquer linguagem processual:

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

Ele simplesmente calcula as diferenças absolutas entre o número fornecido e cada elemento da matriz e devolve um deles com a diferença mínima.

Para os valores de exemplo:

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.

Como prova de conceito, aqui está o código Python que eu usei para mostrar isso em ação:

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)

E, se você realmente precisar dele em Javascript, veja abaixo um arquivo HTML completo que demonstra a função em ação:

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

Agora, lembre-se de que pode haver espaço para maior eficiência se, por exemplo, seus itens de dados forem classificados (que podem ser inferidos a partir dos dados de amostra, mas você não o declara explicitamente). Você pode, por exemplo, usar uma pesquisa binária para encontrar o item mais próximo.

Você também deve ter em mente que, a menos que precise fazer isso muitas vezes por segundo, as melhorias de eficiência serão praticamente imperceptíveis, a menos que seus conjuntos de dados fiquem muito maiores.

Se você não quiser experimentá-lo dessa forma (e pode garantir a matriz é classificada em ordem crescente), este é um bom ponto de partida:

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

Basicamente, usa bracketing e verificação do valor médio para reduzir pela metade o espaço da solução para cada iteração, um O(log N)algoritmo clássico , enquanto a pesquisa seqüencial acima foi 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

Como afirmado, isso não deve fazer muita diferença para conjuntos de dados pequenos ou para coisas que não precisam ser extremamente rápidas, mas é uma opção que você deve considerar.


2
@micha, eu adicionei o código JS eqivalent à resposta, demorou um tempo para mudar os idiomas de um para o qual eu estava mais acostumado :-) #
315

2
Tempo de execução ruim para esse algoritmo se você tiver grandes conjuntos de dados.
precisa saber é o seguinte

4
@ ylun.ca, como não há uma declaração explícita na pergunta de que os dados estão classificados (o exemplo está classificado, mas isso pode ser coincidência), você não pode obter uma eficiência melhor do que O (n). De qualquer forma, para um conjunto de dados desse tamanho, a eficiência é principalmente irrelevante. Mas o seu argumento é válido, portanto, adicionarei notas nesse sentido para, espero, tornar a resposta mais completa.
precisa

1
Obrigado, gostaria de poder votar novamente mais de uma vez! Mais respostas sobre o estouro de pilha devem ter esse tipo de esforço.
Richard Vanbergen 11/11

48

Versão ES6 (2015):

const counts = [4, 9, 15, 6, 2];
const goal = 5;

const output = counts.reduce((prev, curr) => Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);

console.log(output);

Para reutilização, você pode agrupar uma função curry que suporte espaços reservados ( http://ramdajs.com/0.19.1/docs/#curry ou https://lodash.com/docs#curry ). Isso oferece muita flexibilidade, dependendo do que você precisa:

const getClosest = curry((counts, goal) => {
  return counts
    .reduce((prev, curr) => Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);
});

const closestTo5 = getClosest(_, 5);
const closestTo = getClosest([4, 9, 15, 6, 2]);

24

Código de trabalho como abaixo:

var array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];

function closest(array, num) {
  var i = 0;
  var minDiff = 1000;
  var ans;
  for (i in array) {
    var m = Math.abs(num - array[i]);
    if (m < minDiff) {
      minDiff = m;
      ans = array[i];
    }
  }
  return ans;
}
console.log(closest(array, 88));


8
Quanto mais melhor.
Hot Licks

6
Eu diria que esta é uma solução melhor porque usa apenas JavaScript. A resposta aceita usa jQuery, que não foi mencionado na pergunta original e que outras pessoas que estão olhando para essa pergunta podem não estar usando.
23614 Sean Sean Bean

17

Funciona com matrizes não ordenadas

Embora existam boas soluções postadas aqui, o JavaScript é uma linguagem flexível que nos fornece ferramentas para resolver um problema de várias maneiras diferentes. Tudo se resume ao seu estilo, é claro. Se o seu código for mais funcional, você encontrará a variação de redução adequada, ou seja:

  arr.reduce(function (prev, curr) {
    return (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);
  });

No entanto, alguns podem achar isso difícil de ler, dependendo do estilo de codificação. Portanto, proponho uma nova maneira de resolver o problema:

  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

Ao contrário de outras abordagens que encontram o valor mínimo usando Math.min.apply, essa não exige que a matriz de entrada arrseja classificada . Não precisamos nos preocupar com os índices ou classificá-los com antecedência.

Vou explicar o código linha por linha para maior clareza:

  1. arr.map(function(k) { return Math.abs(k - x) })Cria uma nova matriz, essencialmente armazenando os valores absolutos dos números fornecidos (número em arr) menos o número de entrada ( x). Procuraremos o menor número a seguir (que também é o mais próximo do número de entrada)
  2. Math.min.apply(Math, indexArr) Essa é uma maneira legítima de encontrar o menor número na matriz que acabamos de criar antes (nada mais)
  3. arr[indexArr.indexOf(min)]Esta é talvez a parte mais interessante. Encontramos o menor número, mas não temos certeza se devemos adicionar ou subtrair o número inicial ( x). Isso porque costumávamos Math.abs()encontrar a diferença. No entanto, array.mapcria (logicamente) um mapa da matriz de entrada, mantendo os índices no mesmo local. Portanto, para descobrir o número mais próximo, retornamos o índice do mínimo encontrado na matriz fornecida indexArr.indexOf(min).

Eu criei uma caixa demonstrando isso.


1
Eu não sei, mas acho que alguém pode ter dúvidas de desempenho, já que isso é praticamente 3no ES5, mesmo que você responda em 2016 e outras soluções sejam boas, mesmo que esse noob que fez essa pergunta claramente não fosse um programador na época.
Noob

1
Sim, é ótimo ver você aprendendo! A propósito, só falei sobre dúvidas de desempenho, sem argumentar que ele realmente teve um desempenho pior, mas corri os números para você e sua O(n)solução executa cerca de 100k ops / s a ​​menos que @paxdiablo O(log n)em números aleatórios. Ao projetar um algoritmo, sempre classifique primeiro, eles dizem. (Exceto se você sabe o que está fazendo e você tem referências para suportá-lo.)
Noob

1
Suportes para a solução simples. Funciona muito bem para o meu caso de uso (eu não tenho o luxo de ter uma matriz de pré-classificadas como Noob faz.)
jaggedsoft

2
Você pode fazer com que o findClosest retorne uma função de redução de retorno de chamada para torná-lo reutilizável em todas as matrizes: const findClosest = goal => (a,b) => Math.abs(a - goal) < Math.abs(b - goal) ? a : b;
Jakob E

1
Exemplo: [2, 42, 82, 122, 162, 202, 242, 282, 322, 362].reduce(findClosest(80))
Jakob E

11

Para matrizes classificadas (pesquisa linear)

Até agora, todas as respostas concentram-se na pesquisa em toda a matriz. Considerando que sua matriz já está classificada e você realmente deseja apenas o número mais próximo, essa é provavelmente a solução mais rápida:

var a = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];
var target = 90000;

/**
 * Returns the closest number from a sorted array.
 **/
function closest(arr, target) {
  if (!(arr) || arr.length == 0)
    return null;
  if (arr.length == 1)
    return arr[0];

  for (var i = 1; i < arr.length; i++) {
    // As soon as a number bigger than target is found, return the previous or current
    // number depending on which has smaller difference to the target.
    if (arr[i] > target) {
      var p = arr[i - 1];
      var c = arr[i]
      return Math.abs(p - target) < Math.abs(c - target) ? p : c;
    }
  }
  // No number in array is bigger so return the last.
  return arr[arr.length - 1];
}

// Trying it out
console.log(closest(a, target));

Observe que o algoritmo pode ser amplamente aprimorado, por exemplo, usando uma árvore binária.


Embora essa estratégia aqui seja boa, ela tem vários erros de digitação. Exemplo a[i]ou i[0].
Wesley Workman

1
Obrigado, @WesleyWorkman. Apenas os consertei. Espero ter conseguido tudo. A propósito, você também pode editar as respostas de outras pessoas.
Hubert Grzeskowiak 25/03

Onde eu preciso fazer a correção no código respondido acima para obter o valor mais próximo mais alto? Exemplo: [110, 111, 120, 140, 148, 149, 155, 177, 188, 190] Se eu pesquisar 150, devo obter 155 e não 149. Tentei, mas encontrei dificuldade em resolver isso. Poderia ajudar por favor. Graças
user1199842

9

Todas as soluções são projetadas em excesso.

É tão simples quanto:

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

// 5

1
De fato, muito mais direto ao ponto. mas para "obter o número mais próximo da matriz", você ainda precisa selecionar o primeiro elemento da matriz classificada.
Shaya Ulman

6

Essa solução usa o quantificador existencial ES5 Array#some, que permite interromper a iteração, se uma condição for atendida.

Ao contrário de Array#reduce, ele não precisa iterar todos os elementos para um resultado.

Dentro do retorno de chamada, um absoluto deltaentre o valor pesquisado e o valor realitem é obtido e comparado com o último delta. Se maior ou igual, a iteração para, porque todos os outros valores com seus deltas são maiores que o valor real.

Se o deltaretorno de chamada for menor, o item real será atribuído ao resultado e o item deltaserá salvo lastDelta.

Por fim, valores menores com deltas iguais são obtidos, como no exemplo abaixo de 22, que resulta em 2.

Se houver uma prioridade de valores maiores, a verificação delta deverá ser alterada de:

if (delta >= lastDelta) {

para:

if (delta > lastDelta) {
//       ^^^ without equal sign

Isso ficaria com 22o resultado 42(Prioridade de valores maiores).

Esta função precisa de valores classificados na matriz.


Código com prioridade de valores menores:

function closestValue(array, value) {
    var result,
        lastDelta;

    array.some(function (item) {
        var delta = Math.abs(value - item);
        if (delta >= lastDelta) {
            return true;
        }
        result = item;
        lastDelta = delta;
    });
    return result;
}

var data = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];

console.log(21, closestValue(data, 21)); // 2
console.log(22, closestValue(data, 22)); // 2  smaller value
console.log(23, closestValue(data, 23)); // 42
console.log(80, closestValue(data, 80)); // 82

Código com prioridade de maiores valores:

function closestValue(array, value) {
    var result,
        lastDelta;

    array.some(function (item) {
        var delta = Math.abs(value - item);
        if (delta > lastDelta) {
            return true;
        }
        result = item;
        lastDelta = delta;
    });
    return result;
}

var data = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];

console.log(21, closestValue(data, 21)); //  2
console.log(22, closestValue(data, 22)); // 42 greater value
console.log(23, closestValue(data, 23)); // 42
console.log(80, closestValue(data, 80)); // 82


Então você assume que a matriz especificada é classificada ... Isso evita que você demore muito tempo.
Redu

1
olhares matriz do OP classificadas, então sim :)
Nina Scholz

A primeira solução quebra nas entradas que contêm o mesmo número duas vezes. por exemploclosestValue([ 2, 2, 42, 80 ], 50) === 2
Sébastien Vercammen 03/02

@ SébastienVercammen, os dados do op são únicos e classificados.
Nina Scholz

O @NinaScholz OP determinou apenas "Eu tenho uma matriz com números" e "Quero que o número que eu tenho mude para o número mais próximo da matriz" . A matriz de exemplo foi apenas um exemplo. Uma matriz não garante entradas exclusivas.
Sébastien Vercammen

4

ES6

Funciona com matrizes classificadas e não classificadas

Números Inteiros e Flutuantes, Cordas bem-vindas

/**
 * 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

Exemplos:

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

3

Não sei se devo responder a uma pergunta antiga, mas como esse post aparece primeiro nas pesquisas do Google, esperava que você me perdoasse adicionando minha solução e meus 2c aqui.

Sendo preguiçoso, não podia acreditar que a solução para essa pergunta seria um LOOP, então pesquisei um pouco mais e voltei com a função de filtro :

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

Isso é tudo !


1
Então, o que há no limite inferior? Você sempre usa o próximo valor mais alto. Mas sua abordagem me lembra goog.math.clamp(fechamento do Google) apenas com matrizes e sem me preocupar com o limite inferior.
Noob

Sua solução retorna o próximo número mais alto da matriz. Nem o valor mais próximo nem o exato são encontrados.
Hubert Grzeskowiak 01/08/14

2

Minha resposta a uma pergunta semelhante também é responsável por vínculos e é em Javascript puro, embora não use a pesquisa binária, por isso é O (N) e não O (logN):

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

https://stackoverflow.com/a/26429528/986160


2

Gosto da abordagem do Fusion, mas há um pequeno erro. Assim está correto:

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

Também é um pouco mais rápido, porque usa o melhorado for loop .

No final, escrevi minha função assim:

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

Eu testei com console.time()e é um pouco mais rápido que a outra função.


Ei, você pode explicar por que é um improved for loop? Loops invertidos nem sempre são uma melhoria de desempenho.
precisa

Você avalia .lengthapenas uma vez, quando declara i, e para esse loop. Mas eu acho que var i = arr.length;while (i--) {}seria ainda mais rápido
Jon

Eu atualizei minha resposta. Eu mudei para while. Agora é ainda mais rápido.
Jon

0

Uma pesquisa binária ligeiramente modificada na matriz funcionaria.


3
Nossa, isso é bizarro - aparentemente alguém não gosta de pesquisas binárias. (Mesmo que essa é a melhor solução geral.)
Hot Licks

0

Para um pequeno intervalo, a coisa mais simples é ter uma matriz de mapas, onde, por exemplo, a 80ª entrada teria o valor 82 nela, para usar seu exemplo. Para uma faixa muito maior e esparsa, provavelmente o caminho a seguir é uma pesquisa binária.

Com uma linguagem de consulta, você pode consultar valores a alguma distância de ambos os lados do seu número de entrada e depois classificar a lista reduzida resultante. Mas o SQL não tem um bom conceito de "próximo" ou "anterior", para fornecer uma solução "limpa".


0

Outra variante aqui é a faixa circular que conecta a cabeça aos pés e aceita apenas um valor mínimo para a entrada fornecida. Isso me ajudou a obter valores de código de char para um dos algoritmos de criptografia.

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

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

0

O mais eficiente seria uma pesquisa binária. No entanto, mesmo soluções simples podem sair quando o próximo número for uma correspondência adicional à atual . Quase todas as soluções aqui não levam em consideração que a matriz está ordenada e iterada por toda a coisa: /

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

Isso também pode ser executado em não-primitivos, por exemplo, closest(data, 21, item => item.age)

Mude findpara findIndexpara retornar o índice na matriz.


E quanto à matriz não ordenada?
EdG

Para não-ordenado, pegue uma das soluções que não sai, no entanto, se você estiver fazendo o trabalho várias vezes, pode ser mais ideal classificar a matriz uma vez. Como mencionado se a matriz é realmente grande, uma pesquisa binária será mais eficiente que uma linear.
Dominic

0

Para encontrar dois números mais próximos na matriz

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

-5

Aqui está o trecho de código para encontrar o elemento mais próximo de um número de uma matriz na Complexidade O (nlog (n)): -

Entrada: - {1,60,0, -10,100,87,56} Elemento: - 56 Número mais próximo na matriz: - 60

Código fonte (Java):

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

Pós pediu javascript em tags
Shannon Hochkins
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.