Приведи пример, когда следует использовать unordered_set в C++.

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

Ответ

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

Типичный пример: кэш уникальных элементов в процессе обработки данных

#include <unordered_set>
#include <vector>
#include <string>
#include <iostream>

// Задача: отфильтровать дубликаты ID из входного потока
std::vector<int> filter_duplicates(const std::vector<int>& input_ids) {
    std::unordered_set<int> seen_ids; // Храним уже обработанные ID
    std::vector<int> unique_ids;
    unique_ids.reserve(input_ids.size());

    for (int id : input_ids) {
        // Проверка и вставка за O(1) в среднем
        if (seen_ids.insert(id).second) { // .second == true, если вставка прошла (элемента не было)
            unique_ids.push_back(id);
        }
        // Альтернативная проверка: if (seen_ids.find(id) == seen_ids.end()) { ... }
    }
    return unique_ids;
}

int main() {
    std::vector<int> raw_data = {101, 205, 101, 308, 205, 422};
    auto filtered = filter_duplicates(raw_data);
    // filtered содержит {101, 205, 308, 422} (порядок может быть любым)

    for (int id : filtered) {
        std::cout << id << ' ';
    }
    return 0;
}

Ключевые сценарии использования unordered_set:

  • Удаление дубликатов из коллекции.
  • Быстрая проверка наличия элемента (например, валидация токена из чёрного списка).
  • Реализация отношений "многие ко многим" (например, хранение множества друзей пользователя).
  • Кэширование результатов вычислений, где ключом является входной параметр.
Сравнение с std::set: Критерий std::unordered_set std::set
Средняя сложность операций O(1) O(log n)
Порядок элементов Не гарантирован Отсортирован по возрастанию
Требования к элементам Должен быть определён std::hash<Key> и operator== Должен быть определён operator< или кастомный компаратор
Производительность Выше при хорошей хеш-функции Предсказуема, но ниже

Важно: Для пользовательских типов необходимо специализировать std::hash и определить operator==.