std::map
Упорядоченное хранилище пар ключ—значение
«std::map» — бесплатный урок C++ Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.
Что такое std::map?
std::map хранит пары ключ—значение, отсортированные по ключу. Каждый ключ уникален, а поиск, вставка и удаление выполняются за логарифмическое время.
- Ключи хранятся в отсортированном порядке.
- В основе лежит сбалансированное двоичное дерево поиска.
#include <iostream>
#include <map>
int main() {
std::map<std::string, int> ages;
ages["Alice"] = 30;
ages["Bob"] = 25;
std::cout << "Alice is " << ages["Alice"] << '\n';
return 0;
}Вставка элементов
Для вставки можно использовать operator[], insert() или emplace(). Использование [] для отсутствующего ключа создаёт его со значением по умолчанию.
#include <iostream>
#include <map>
int main() {
std::map<std::string, int> m;
m["one"] = 1;
m.insert({"two", 2});
m.emplace("three", 3);
std::cout << m.size() << " entries\n";
return 0;
}Перебор в отсортированном порядке
При переборе std::map ключи посещаются в порядке возрастания. Каждый элемент является объектом std::pair с .first (ключом) и .second (значением).
#include <iostream>
#include <map>
int main() {
std::map<std::string, int> m{{"banana", 3}, {"apple", 5}, {"cherry", 1}};
for (const auto& p : m) {
std::cout << p.first << " = " << p.second << '\n';
}
return 0;
}Поиск ключей
Используйте find() для безопасного поиска ключа. Он возвращает итератор на элемент или end(), если ключ не найден.
#include <iostream>
#include <map>
int main() {
std::map<std::string, int> m{{"x", 10}, {"y", 20}};
auto it = m.find("y");
if (it != m.end()) {
std::cout << "Found y = " << it->second << '\n';
} else {
std::cout << "Not found\n";
}
return 0;
}Проверка существования
Чтобы проверить наличие ключа, не создавая его, используйте count() (возвращает 0 или 1) или contains() в C++20.
#include <iostream>
#include <map>
int main() {
std::map<std::string, int> m{{"a", 1}};
std::cout << m.count("a") << '\n';
std::cout << m.count("z") << '\n';
return 0;
}Обновление значений
Повторное присваивание ключу обновляет его значение на месте. В map хранится только одно значение для каждого ключа.
#include <iostream>
#include <map>
int main() {
std::map<std::string, int> score;
score["player"] = 10;
score["player"] += 5;
std::cout << score["player"] << '\n';
return 0;
}Удаление элементов
erase() удаляет элемент по ключу или итератору. При передаче ключа он возвращает количество удалённых элементов.
#include <iostream>
#include <map>
int main() {
std::map<std::string, int> m{{"a", 1}, {"b", 2}, {"c", 3}};
m.erase("b");
std::cout << m.size() << " left\n";
for (const auto& p : m) std::cout << p.first << ' ';
std::cout << '\n';
return 0;
}Использование at()
at() возвращает ссылку на значение ключа и выбрасывает std::out_of_range, если ключ отсутствует. В отличие от [], он никогда не выполняет вставку.
#include <iostream>
#include <map>
int main() {
std::map<std::string, int> m{{"k", 42}};
std::cout << m.at("k") << '\n';
std::cout << "size: " << m.size() << '\n';
return 0;
}Подсчёт частот слов
Классическое применение std::map — подсчёт вхождений. Оператор [] инициализирует новые ключи значением 0 по умолчанию, поэтому ++ сразу работает.
#include <iostream>
#include <map>
#include <string>
int main() {
std::string words[] = {"cat", "dog", "cat", "bird", "dog", "cat"};
std::map<std::string, int> freq;
for (const auto& w : words) freq[w]++;
for (const auto& p : freq) std::cout << p.first << ": " << p.second << '\n';
return 0;
}Структурированные привязки
В C++17 можно распаковывать каждую пару с помощью структурированных привязок, присваивая понятные имена ключу и значению.
#include <iostream>
#include <map>
int main() {
std::map<std::string, int> m{{"red", 1}, {"green", 2}};
for (const auto& [name, value] : m) {
std::cout << name << " -> " << value << '\n';
}
return 0;
}Проверка на пустоту
empty() сообщает, нет ли в map элементов, а clear() удаляет всё сразу.
#include <iostream>
#include <map>
int main() {
std::map<int, int> m{{1, 1}, {2, 4}};
std::cout << std::boolalpha << m.empty() << '\n';
m.clear();
std::cout << m.empty() << '\n';
return 0;
}Быстрая проверка
Проверьте, насколько хорошо Вы поняли порядок элементов в std::map.
Итоги
Вы узнали, что std::map:
- хранит уникальные отсортированные ключи, сопоставленные со значениями;
- поддерживает
insert,[],find,count,atиerase; - перебирается в порядке возрастания ключей, а пары можно распаковывать с помощью структурированных привязок.
Далее Вы познакомитесь с std::set, предназначенным для хранения только уникальных отсортированных значений.
Часто задаваемые вопросы
Урок «std::map» бесплатный?
Да — полный текст урока «std::map» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.
Чему я научусь в уроке «std::map»?
Упорядоченное хранилище пар ключ—значение Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C++ Academy?
Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «std::map»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C++ Academy?
Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.