ecwd assigment
Условия
Дан простой текстовый файл с IPv4 адресами. Одна строка – один адрес, примерно так:
145.67.23.4
8.34.5.23
89.54.3.124
89.54.3.124
3.45.71.5
...
Файл в размере не ограничен и может занимать десятки и сотни гигабайт.
Необходимо посчитать количество уникальных адресов в этом файле, затратив как можно меньше памяти и времени. Существует «наивный» алгоритм решения данной задачи (читаем строка за строкой, кладем строки в HashSet), желательно чтобы ваша реализация была лучше этого простого, наивного алгоритма.
Немного деталей:
- Использовать можно только возможности стандартной библиотеки Java/Kotlin
- Писать нужно на Java (версия 11 и выше) или Kotlin.
- В задании должен быть рабочий метод main(), это должно быть готовое приложение, а не просто библиотека
- Сделанное задание необходимо разместить на GitHub
Решение
Идея следующая: нам нужен только массив с размерностью со все возможные адреса (четыре байта адреса = один int), где каждый элемент хранит бит «этот адрес был в списке».
После обработки файла достаточно просто просуммировать накопленное.
Чтобы не сорить памятью, в качестве членов массива выбираем byte — boolean всё равно займет столько же (так устроены компьютеры), но теперь мы можем запоминать 8 адресов в одном за раз и сократить размер массива втрое.
Итог: 512 мегабайт памяти и один проход.
Альтернативный вариант (если возникнет требование экономить память или лог будет с ipv6): конвертировать адреса в число нужного размера и запоминать в связном списке, вставляя с учетом сортировки (для поиска).
Это экономит память (список адресов предполагает, что их взяли из лога и они часто повторяются) и дает log n вычислений.
В таком случае список имплементим тоже самостоятельно, чтобы не тратить память на боксинг-анбоксинг в коллекциях.