Да, это возможно. Согласно документации:
Метод возвращает индекс ключа поиска, если он содержится в списке; в противном случае
(-(insertion point) - 1)
. Точка вставки определяется как точка, в которой ключ будет вставлен в список: индекс первого элемента больше, чем ключ, или list.size()
, если все элементы в списке меньше указанного ключа. Обратите внимание, что это гарантирует, что возвращаемое значение будет> = 0 в том и только в том случае, если ключ найден.
Таким образом, регулируя возвращаемый индекс, вы можете получить следующее значение (или даже предыдущее значение), ближайшее место, где было бы найдено желаемое значение.
Это работает следующим образом:
- генерирует
list
значений от 1 до 20. Вызовите затем n
- создайте лямбду,
fn
для применения к каждому n. - создайте
Comparator<Integer> comp
, который использует fn
для сравнения - вызовите двоичную сортировку с помощью
list
, n
и comp
- используют возвращаемый индекс для поиска ближайшего
n
для f(n)
Вот пример, который возвращает ближайшее значение к f(n)
Random r = new Random(23);
// define f(n)
Function<Integer, Integer> f = x -> x*x + 2 * x + 3;
Comparator<Integer> comp =
(a, b) -> Integer.compare(f.apply(a), f.apply(b));
for (int i = 0; i < 5; i++) {
// generate a list of f(n) values.
List<Integer> list = r.ints(10, 1, 20).distinct()
.sorted().boxed()
.collect(Collectors.toList());
List<Integer> fns = list.stream().map(f::apply).collect(Collectors.toList());
// Choose a random n
int n = r.nextInt(20);
System.out.println("fns = " + fns);
System.out.println("n = " + list);
// now find nearest f(n) in the list.
int fn = f.apply(n);
System.out.println("searching for nearest value to f(" + n
+ ") [" + fn + "]");
int index = Collections.binarySearch(list, n, comp);
// Now determine the index of the value that
// meets the requirements.
if (index >= 0) {
System.out
.println("Exact answer = " + list.get(index));
System.out.println();
} else {
int nearest;
index = -index - 1;
// check end cases
if (index == 0) {
nearest = list.get(index);
} else if (index == list.size()) {
nearest = list.get(index - 1);
} else {
// check middle cases
int lowerValue = list.get(index - 1);
int higherValue = list.get(index);
if (n - lowerValue > higherValue - n) {
nearest = higherValue;
} else {
nearest = lowerValue;
}
}
System.out.println(
"Nearest result to " + n + " is " + nearest);
System.out.println();
}
}
}
Отпечатки:
fn = [18, 51, 66, 83, 102, 123, 171, 291, 363]
n = [3, 6, 7, 8, 9, 10, 12, 16, 18]
searching for nearest value to f(14) [227]
Nearest result to 14 is 12
fn = [6, 11, 38, 51, 83, 198, 326]
n = [1, 2, 5, 6, 8, 13, 17]
searching for nearest value to f(17) [326]
Exact answer = 17
fn = [11, 18, 83, 146, 171, 227, 291, 326]
n = [2, 3, 8, 11, 12, 14, 16, 17]
searching for nearest value to f(0) [3]
Nearest result to 0 is 2
fn = [6, 18, 27, 51, 66, 198, 363]
n = [1, 3, 4, 6, 7, 13, 18]
searching for nearest value to f(1) [6]
Exact answer = 1
fn = [11, 18, 66, 102, 146, 198, 258, 291, 326]
n = [2, 3, 7, 9, 11, 13, 15, 16, 17]
searching for nearest value to f(0) [3]
Nearest result to 0 is 2