Подтвердить что ты не робот

Использование java-карты для поиска диапазона

У меня есть прецедент, где, если число лежит между 0-10, оно должно возвращать 0, а если оно лежит между 11-20, оно должно возвращать 1 и т.д.

0 => 0-3, (0 and 3 are inclusive)
1 => 4-15, (4 and 15 are inclusive)
2 => 16-40, (16 and 40 are inclusive)
3 => 41-88, (41 and 88 are inclusive)
5 => 89-300 (89 and 300 are inclusive)

Я думал, как я могу реализовать и думать о java-картах, но он не позволяет искать диапазон

Мне интересно что-то вроде этого, у меня есть функция

int foo() {

}

если foo возвращает 5, так как он лежит между 0 и 10, я использовал бы 0, если foo return 25 использовал бы 2.

Любые идеи

Изменить: на самом деле диапазоны не такие простые, как 0-10, 11-20. Я хочу иметь возможность выполнять поиск по диапазону. Прошу прощения за путаницу. На основе запросов я добавил правильный пример, числа непрерывны

4b9b3361

Ответ 1

Я могу придумать ряд возможных решений для более общей проблемы, где диапазоны неравномерны и есть "дырки". Самые простые:

  • Просто введите Map для всех допустимых значений ключа, при сопоставлении нескольких ключей с тем же значением. Предполагая, что вы используете HashMaps, это должен быть самый эффективный (O (1) поиск), хотя у вас больше времени на настройку, и вы используете больше места.
  • Используйте навигационную карту и используйте floorEntry(key) для поиска. Это должно быть менее эффективным (O (log (N) поиск), но более экономичным.

Здесь используется решение с использованием NavigableMaps, которое позволяет "дыры" в отображении.

private static class Range {
   public int upper, value;
   ...
}

NavigableMap<Integer, Range> map = new TreeMap<Integer, Range>();
map.put(0, new Range(3, 0));       // 0..3     => 0
map.put(5, new Range(10, 1));      // 5..10    => 1
map.put(100, new Range(200, 2));   // 100..200 => 2

// To do a lookup for some value in 'key'
Map.Entry<Integer,Range> entry = map.floorEntry(key);
if (entry == null) {
    // too small
} else if (key <= entry.getValue().upper) {
    return entry.getValue().value;
} else {
    // too large or in a hole
}

С другой стороны, если нет "дырок", решение проще:

NavigableMap<Integer, Integer> map = new TreeMap<Integer, Integer>();
map.put(0, 0);    // 0..4     => 0
map.put(5, 1);    // 5..10    => 1
map.put(11, 2);   // 11..200  => 2

// To do a lookup for some value in 'key'
if (key < 0 || key > 200) {
    // out of range
} else {
   return map.floorEntry(key).getValue();
}

Ответ 2

Псевдо-код:

  • Сохраните границы диапазона в плоском массиве: new int[] {0, 3, 5, 15, 100, 300}.
  • Двоичный поиск по массиву, как будто вставка числа в массив. См. Arrays.binarySearch().
  • Если точка ввода ровная, номер не помещается в любой диапазон.
  • Если точка ввода нечетна, она вписывается в соответствующий диапазон. Например, точка вставки для 10 в вышеприведенном массиве будет 3, помещая ее между 5 и 15, поэтому она принадлежит во втором диапазоне.

Ответ 3

В более общем случае, который не может быть решен с помощью арифметики, вы можете создать TreeMap с соответствующим компаратором. Добавьте сопоставления для граничных значений, а затем используйте функцию topEntry или floorEntry, чтобы найти соответствующее совпадение.

Ответ 4

Я думаю, что вы хотите, это что-то вроде строк foo()/10, но это даст вам диапазоны, слегка отложенные от запрошенных вами. Вы всегда можете просто сравнивать с двумя конечными точками для каждого элемента вашей "карты", если они не следуют легкому шаблону.

Ответ 5

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

Другим способом было бы заполнить карту всеми элементами в диапазоне и добавить сопоставление для каждого.

Какой из них более эффективен, зависит от того, нужно ли вам многократно запрашивать все числа в диапазоне (используйте последнее решение) или просто некоторые из чисел несколько раз (используйте первый)