Моя единственная идея - разобрать файл и превратить диапазоны IP-адресов в просто целые числа (умножить на 10/100, если в нем отсутствуют цифры) ...
Если следовать этому подходу, вы, вероятно, захотите умножить на 256 ^ 3, 256 ^ 2, 256 и 1 соответственно для A, B, C и D в адресе A.B.C.D. Это эффективно воссоздает IP-адрес как 32-разрядное число без знака.
... и поместите их в список, а также поместите нижний из диапазонов в хеш в качестве ключа со значением местоположения в качестве значения. Сортируйте список и выполните слегка измененный двоичный поиск. Если индекс нечетный, -1 и посмотрите в хэш. Если это даже, просто посмотрите в хэш.
Я бы предложил создать непрерывный массив (std::vector
), содержащий структуры с нижним и верхним диапазоном (и названием местоположения - обсуждается ниже). Тогда, как вы говорите, вы можете выполнить двоичный поиск диапазона, включающего определенное значение, без каких-либо нечетных / четных хлопот.
Использование нижнего конца диапазона в качестве ключа в хэше - это один из способов избежать пространства для имен местоположений в массиве, но, учитывая среднее количество символов в названии города, вероятный размер указателей, выбор между малонаселенной хеш-таблицей и длинными списками смещения для поиска в последовательных альтернативных контейнерах или дальнейшего косвенного обращения к контейнерам произвольной длины - вам, скорее всего, придется отчаянно пытаться потрудиться. В первом случае сохранение местоположения в struct вместе с диапазоном значений IP кажется хорошим.
Кроме того, вы можете создать дерево, например, на основе отдельные значения IP 0-255: каждый уровень в дереве может быть либо массивом из 256 значений для прямой индексации, либо отсортированным массивом заполненных значений. Это может уменьшить количество сравнений значений IP, которые вам, вероятно, понадобятся (от O (log2N) до O (1)).