Я имею массив упорядоченного двойника большого размера, например:
[2.1,3.4,3.6,4.1]
Теперь я генерирую, в некотором роде, двойной номер, например:
3.51
Мне нужно создать функцию на Java, которая получит массив и число и даст мне ближайшее значение в массиве этого числа. В этом примере 3.6.
Как я могу сделать это наиболее эффективным способом? Потому что у меня может быть массив из 300 000 двойных и нужно часто выполнять эту операцию. Тогда я не могу сделать простой сравнения.
Изменить: я сделал это, в каком-то тесте результат правильный, потому что вы правы?
int pos = Arrays.binarySearch(allTime.times, value);
double out;
if(pos >= 0)
{
// System.out.println(allTime.times[pos]);
out = allTime.times[pos];
}
else if(pos == -1)
{
// System.out.println(allTime.times[0]);
out = allTime.times[0];
}
else
{
int insertionPoint = -pos-1;
if(insertionPoint < allTime.times.length)
{
if(allTime.times[insertionPoint] - value < value - allTime.times[insertionPoint-1])
// System.out.println(allTime.times[insertionPoint] );
out = allTime.times[insertionPoint];
else
// System.out.println(allTime.times[insertionPoint-1] );
out = allTime.times[insertionPoint-1];
}
else
// System.out.println(allTime.times[allTime.times.length -1]);
out = allTime.times[allTime.times.length -1];
}
Ответ Jimmy T не обрабатывает угловой регистр, например, если число поиска падает до 0-го индекса или если оно выходит за последний индекс.
Вот исправленный
double searchNearest(double[] array, double searchNumber) {
int pos = Arrays.binarySearch(array, searchNumber);
if (pos >= 0)
return searchNumber;
else {
int insertionPoint = -pos - 1;
if (insertionPoint > 0 && insertionPoint < array.length) {
if ((searchNumber - array[insertionPoint - 1]) < (array[insertionPoint] - searchNumber)) {
return array[insertionPoint - 1];
} else {
return array[insertionPoint];
}
} else {
return insertionPoint == 0 ? array[0] : array[array.length - 1];
}
}
}
insertionPoint
не может быть меньше нуля.
Arrays.binarySearch
также работает для элементов, не содержащихся в массиве.
int pos = Arrays.binarySearch(arr, value);
Если значение не содержится, оно возвращает отрицательное значение, которое описывает, где должно быть значение: (-(insertion point) - 1)
.
Затем просто найдите, какое из двух соседних значений является правильным.
if(pos < 0)
{
int insertionPoint = -pos-1;
if(insertionPoint == arr.length) //value is bigger than every value in array
//arr[insertionPoint-1] is the nearest value
else if(insertionPoint == 0) //value is smaller than every value in array
//arr[0] is the nearest value
else if(value-arr[insertionPoint-1] < arr[insertionPoint]-value)
//arr[insertionPoint-1] is the nearest value
else
//arr[insertionPoint] is the nearest value
}else
//arr[pos] has the same value
Значение в index insertPoint
больше value
. Я также рассмотрел случай, что значение содержится в массиве.