В каких прикладных задачах использовал std::unordered_map?

«В каких прикладных задачах использовал std::unordered_map?» — вопрос из категории STL, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

std::unordered_map (хеш-таблица) — мой инструмент для задач, где критична скорость поиска по ключу (амортизированное O(1)), а порядок элементов не важен.

Конкретные примеры из опыта:

  1. Кеширование результатов вычислений:

    std::unordered_map<std::string, std::complex<double>> calculationCache;
    
    const std::complex<double>& getCachedResult(const std::string& input) {
        auto it = calculationCache.find(input);
        if (it != calculationCache.end()) {
            return it->second; // Кеш-хит
        }
        // Дорогое вычисление...
        std::complex<double> result = performHeavyCalculation(input);
        auto [newIt, inserted] = calculationCache.emplace(input, std::move(result));
        return newIt->second;
    }
  2. Быстрый поиск по идентификаторам (ID → объект):

    std::unordered_map<uint64_t, std::shared_ptr<Player>> playerRegistry;
    
    std::shared_ptr<Player> findPlayer(uint64_t playerId) {
        if (auto it = playerRegistry.find(playerId); it != playerRegistry.end()) {
            return it->second;
        }
        return nullptr;
    }
  3. Подсчет частот (гистограмма):

    std::unordered_map<int, size_t> frequencyMap;
    for (const auto& value : sensorReadings) {
        ++frequencyMap[value];
    }
    // Найти наиболее часто встречающееся значение
    auto mostFrequent = std::max_element(frequencyMap.begin(), frequencyMap.end(),
                                         [](const auto& a, const auto& b) { return a.second < b.second; });

Ключевые отличия от std::map и важные нюансы:

  • Скорость: unordered_map обычно быстрее для больших datasets, так как использует хеширование, а не красно-черное дерево.
  • Память: Может потреблять больше из-за buckets и load factor.
  • Ключ: Требует наличия std::hash<Key> и оператора ==. Для пользовательских типов их нужно определить.
  • Инвалидация итераторов: Операции вставки могут инвалидировать все итераторы при рехешировании.