Files
eduplan-cpp-eltex/diag/tasks/10_hash/task.md
T

2.3 KiB
Raw Blame History

Задача 10 — хеш-таблица с открытой адресацией (C++)

Свой контейнер, без std::unordered_map. Разрешение коллизий — линейное зондирование (linear probing), ёмкость — степень двойки, при загрузке > 0.7 таблица перехешируется вдвое. Индексация — через маску idx & (capacity - 1), а не %.

class HashTable {
public:
    explicit HashTable(std::size_t initial_capacity = 16);
    void        put(int key, int value);        // обновляет значение, если ключ уже есть
    bool        get(int key, int& out) const;   // false — ключа нет
    bool        erase(int key);                 // false — ключа не было
    std::size_t size() const;
    std::size_t capacity() const;               // степень двойки, >= 16
};

Требования:

  • put 100 000 ключей — суммарно быстрее 2 секунд (в среднем O(1));
  • ключи с совпадающими младшими битами (например, все кратные 16) обязаны находиться — это проверка зондирования, а не «повезло с хешем»;
  • после 100 000 вставок capacity() растёт (степень двойки, загрузка ≤ 0.7), а size() честно считает элементы, включая обновления существующих ключей;
  • удаление должно работать: после erase ключ не находится, а поиск другого ключа, стоявшего за ним в цепочке зондирования, по-прежнему работает.

Проверка: python3 grade.py 10. Критерий: все ok, сборка без предупреждений, ASAN/UBSAN чистые.

Разбор после сдачи: почему ёмкость — степень двойки; чем линейное зондирование лучше цепочек по кэшу и хуже по кластеризации; как tombstone-метки спасают поиск после удаления.