Нахождение ближайшего числа в массиве - PullRequest
12 голосов
/ 06 февраля 2009

Сначала в массиве мы должны найти, существует ли желаемое число в этом или нет? Если нет, то как мне найти номер ближе к указанному желаемому числу в Java?

Ответы [ 11 ]

12 голосов
/ 06 февраля 2009

Идея:

int nearest = -1;
int bestDistanceFoundYet = Integer.MAX_INTEGER;
// We iterate on the array...
for (int i = 0; i < array.length; i++) {
  // if we found the desired number, we return it.
  if (array[i] == desiredNumber) {
    return array[i];
  } else {
    // else, we consider the difference between the desired number and the current number in the array.
    int d = Math.abs(desiredNumber - array[i]);
    if (d < bestDistanceFoundYet) {
      // For the moment, this value is the nearest to the desired number...
      bestDistanceFoundYet = d; // Assign new best distance...
      nearest = array[i];
    }
  }
}
return nearest;
3 голосов
/ 06 февраля 2009

Другое распространенное определение «ближе» основано на квадрате разности. Схема похожа на ту, которую предоставляет romaintaz, за исключением того, что вы вычислите

long d = ((long)desiredNumber - array[i]);

, а затем сравните (d * d) с ближайшим расстоянием.

Примечание , которое я набрал d как long вместо int, чтобы избежать переполнения, которое может произойти даже с абсолютным значением вычисление на основе. (Например, подумайте о том, что происходит, когда desiredValue составляет не менее половины максимального 32-разрядного значения со знаком, а массив содержит значение с соответствующей величиной, но отрицательным знаком.)

Наконец, я напишу метод, который возвращает индекс найденного значения, а не само значение. В любом из этих двух случаев:

  • когда массив имеет нулевую длину, а
  • если вы добавите параметр «допуск», который ограничивает максимальную разницу, которую вы считаете совпадением,

вы можете использовать -1 в качестве внеполосного значения, аналогичного спецификации indexOf.

2 голосов
/ 26 сентября 2014

// Это будет работать

public int nearest(int of, List<Integer> in)
{
int min = Integer.MAX_VALUE;
int closest = of;

for (int v : in) 
{
    final int diff = Math.abs(v - of);

    if (diff < min) 
    {
        min = diff;
        closest = v;
    }
}
return closest;
}
1 голос
/ 06 февраля 2009

Псевдокод для возврата списка ближайших целых чисел.

myList = new ArrayList();          

if(array.length==0) return myList; 

myList.add(array[0]);

int closestDifference = abs(array[0]-numberToFind);

for (int i = 1; i < array.length; i++) {

 int currentDifference= abs(array[i]-numberToFind);

  if (currentDifference < closestDifference) {

    myList.clear();

    myList.add(array[i]);

         closestDifference = currentDifference;

  } else {

    if(currentDifference==closestDifference) {

        if( myList.get(0) !=array[i]) && (myList.size() < 2) {

            myList.add(array[i]);

        }
            }

       }

}

return myList;
1 голос
/ 06 февраля 2009

Если массив отсортирован, тогда выполните модифицированный двоичный поиск. В основном, если вы не нашли номер, то в конце поиска верните нижнюю границу.

0 голосов
/ 12 февраля 2013
// paulmurray's answer to your question is really the best :

// The least square solution is way more elegant, 
// here is a test code where numbertoLookFor
// is zero, if you want to try ...

import java.util.* ;

public class main {
    public static void main(String[] args) 
    {
        int[] somenumbers = {-2,3,6,1,5,5,-1} ;
        ArrayList<Integer> l = new ArrayList<Integer>(10) ;
        for(int i=0 ; i<somenumbers.length ; i++)
        {
            l.add(somenumbers[i]) ;
        }
        Collections.sort(l, 
                new java.util.Comparator<Integer>()
                {
                    public int compare(Integer n1, Integer n2)
                    {
                        return n1*n1 - n2*n2 ;
                    }
                }
        ) ;
        Integer first = l.get(0) ;
        System.out.println("nearest number is " + first) ;  
    }
}
0 голосов
/ 19 сентября 2012

Несколько вещей, на которые стоит обратить внимание:

1 - Вы можете преобразовать массив в список, используя

Arrays.asList(yourIntegerArray);

2 - Используя список, вы можете просто использовать indexOf ().

3 - Рассмотрим сценарий, в котором у вас есть список некоторой длины, вы хотите, чтобы число было ближе к 3, вы уже нашли, что 2 находится в массиве, и вы знаете, что 3 нет. Не проверяя другие числа, вы можете с уверенностью сделать вывод, что 2 - лучшее, потому что невозможно быть ближе. Однако я не уверен, как работает indexOf (), так что на самом деле это может не ускорить вас.

4 - Расширяя 3, скажем, что indexOf () занимает не больше времени, чем получение значения по индексу. Затем, если вы хотите, чтобы число, близкое к 3 в массиве, и вы уже нашли 1, и вам нужно было проверить еще много чисел, будет быстрее просто проверить, есть ли 2 или 4 в массиве.

5 - Расширяя 3 и 4, я думаю, что можно применить это к плавающим и двойным числам, хотя для этого потребуется, чтобы вы использовали размер шага меньше 1 ... вычисляя, как мало кажется за рамками вопрос, однако.

0 голосов
/ 07 февраля 2009
int[] somenumbers = getAnArrayOfSomenumbers();
int numbertoLookFor = getTheNumberToLookFor();

boolean arrayContainsNumber = 
   new HashSet(Arrays.asList(somenumbers))
      .contains(numbertoLookfor);

Это тоже быстро.

О - ты хотел найти ближайший номер? В этом случае:

int[] somenumbers = getAnArrayOfSomenumbers();
int numbertoLookFor = getTheNumberToLookFor();

ArrayList<Integer> l = new ArrayList<Integer>(
  Arrays.asList(somenumbers)
);
Collections.sort(l);
while(l.size()>1) {
  if(numbertoolookfor <= l.get((l.size()/2)-1)) {
    l = l.subList(0, l.size()/2);
  }
  else {
    l = l.subList(l.size()/2, l.size); 
  }
}

System.out.println("nearest number is" + l.get(0));

Ох - подожди: ты был после решения наименьших квадратов?

Collections.sort(l,  new Comparator<Integer>(){
  public int compare(Integer o1, Integer o2) {
    return (o1-numbertoLookFor)*(o1-numbertoLookFor) - 
           (o2-numbertoLookFor)*(o2-numbertoLookFor);
  }});

System.out.println("nearest number is" + l.get(0));
0 голосов
/ 06 февраля 2009
   int d = Math.abs(desiredNumber - array[i]);
    if (d < bestDistanceFoundYet) {
      // For the moment, this value is the nearest to the desired number...
      nearest = array[i];
    }

Таким образом, вы находите последнее число ближе к желаемому, потому что bestDistanceFoundYet * ​​1003 * является константой, а d запоминает последнее значение, передавая if (d <...) </em>.

Если вы хотите найти более близкое число С ЛЮБОЙ РАССТОЯНИЕЮ по желаемому номеру ( d не имеет значения), вы можете запомнить последнее возможное значение. Если вы можете проверить

if(d<last_d_memorized){ //the actual distance is shorter than the previous
    // For the moment, this value is the nearest to the desired number...
          nearest = array[i];
    d_last_memorized=d;//is the actual shortest found delta 
}
0 голосов
/ 06 февраля 2009

Не хватает только семантики ближе.

Что вы делаете, если ищете шесть, а в вашем массиве четыре и восемь?

Какой из них ближе всего?

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