Приведи пример использования std::set в C++.

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

Ответ

std::set — это ассоциативный контейнер STL, хранящий уникальные элементы (ключи) в отсортированном порядке. Реализован, как правило, в виде красно-черного дерева.

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

  1. Хранение уникальной коллекции с автоматической сортировкой.
  2. Быстрая проверка принадлежности элемента (O(log n)).
  3. Работа с упорядоченными диапазонами (нижняя/верхняя граница).

Практический пример: Управление списком уникальных ID пользователей онлайн.

#include <iostream>
#include <set>
#include <string>

int main() {
    // 1. Создание и инициализация
    std::set<std::string> onlineUsers = {"alice123", "bob_developer", "charlie"};

    // 2. Вставка элементов. Дубликаты игнорируются.
    auto [it1, inserted1] = onlineUsers.insert("diana");
    if (inserted1) {
        std::cout << "Diana joined.n";
    }

    auto [it2, inserted2] = onlineUsers.insert("alice123"); // Дубликат!
    if (!inserted2) {
        std::cout << "User alice123 is already online.n";
    }

    // 3. Поиск элемента (быстрый, O(log n))
    std::string searchName = "bob_developer";
    if (onlineUsers.find(searchName) != onlineUsers.end()) {
        std::cout << searchName << " is online.n";
    }

    // 4. Удаление элемента
    onlineUsers.erase("charlie");
    std::cout << "Charlie left.n";

    // 5. Обход в отсортированном порядке (по возрастанию)
    std::cout << "nCurrently online (sorted):n";
    for (const auto& user : onlineUsers) { // Используется const-итератор
        std::cout << "- " << user << std::endl;
    }
    // Вывод будет: alice123, bob_developer, diana

    // 6. Использование нижней границы (lower_bound)
    // Найдём первого пользователя с ID >= "c"
    auto lb = onlineUsers.lower_bound("c");
    if (lb != onlineUsers.end()) {
        std::cout << "nFirst user starting from 'c': " << *lb << std::endl; // diana
    }

    // 7. Получение размера
    std::cout << "Total unique users online: " << onlineUsers.size() << std::endl;

    return 0;
}

Ключевые особенности std::set:

  • Уникальность и сортировка: Гарантированы автоматически.
  • Сложность операций: Вставка, удаление, поиск — логарифмические (O(log n)).
  • Неизменяемость ключей: Элементы set являются константными (const Key), чтобы не нарушить порядок в дереве. Для изменения нужно удалить старый и вставить новый элемент.
  • Альтернатива: std::unordered_set — если нужна уникальность, но не важен порядок (хэш-таблица, O(1) в среднем).