Определить, находится ли целое число в нескольких диапазонах целых чисел

Допустим, у вас есть целое число n, Допустим, у вас есть список непересекающихся целочисленных диапазонов, например:

1-9
99-105
160-205
503-600
// many more thousands of ranges, etc ....

Я мог бы очень легко перебрать все это и проверить, находится ли n между каждой из границ, и вернуть true, если он есть. Это было бы O(n), что плохо. Можно ли это сделать в O(1)?

Некоторые правила:

  • Сами целые числа очень велики, а диапазоны очень широки, поэтому было бы невозможно просто получить полный список допустимых целых чисел и использовать что-то вроде Set для поиска O (1). Хранение такого количества целых чисел в памяти слишком дорого. Я могу только хранить список границ.
  • Я собираюсь запустить этот тест много раз, поэтому я могу заранее преобразовать список в некоторую структуру данных, если это сделает последующие поиски более эффективными.

Я чувствую, что могу получить двоичные представления этих диапазонов и построить дерево, которое даст O(log(n)).

Мой реальный вопрос

У меня есть список IP-адресов подсетей. Мне нужно проверить, есть ли данный IP в любой из этих подсетей. У меня будет много много IP-адресов для проверки. Я могу конвертировать IP в целое число (1.2.3.4 => 1*2^32 + 2*2^16 + 3*2^8 + 4). И я могу конвертировать подсети аналогично. Это приравнивается к вопросу "проще объяснить" выше.

Спасибо!

1 ответ

Сохранение диапазонов в отсортированном векторе и поиск значения с помощью std::lower_bound - это O(log(n)).

Какой размер целого числа вам нужен для IP 200.200.200.200 с этим алгоритмом? Почему не только 200200200200?

Дерево четырех ветвей для IP ABCD для хранения подсетей кажется более подходящим.

Другие вопросы по тегам