Контейнеры STL
Часть раздела Объектно-ориентированное программирование путешествия по C++ на Coddy. Урок 71 из 104.
STL containers — это шаблонные классы, которые хранят и организуют коллекции объектов. each тип containers оптимизирован для различных шаблонов access и операций. Выбор подходящего контейнера для ваших потребностей может значительно повлиять на производительность вашей программы.
containers поддерживают elements в определённом порядке:
#include <vector>
#include <list>
std::vector<int> vec = {1, 2, 3}; // Динамический массив, быстрый произвольный доступ
vec.push_back(4); // Добавление в конец: O(1) амортизированное
int x = vec[2]; // Доступ по индексу: O(1)
std::list<int> lst = {1, 2, 3}; // Двусвязный список
lst.push_front(0); // Добавление в начало: O(1)
lst.push_back(4); // Добавление в конец: O(1)Ассоциативные containers хранят elements в отсортированном порядке для быстрого поиска:
#include <map>
#include <set>
std::set<int> s = {3, 1, 4, 1}; // Уникальные отсортированные элементы: {1, 3, 4}
s.insert(2); // Вставка: O(log n)
bool found = s.count(3); // Проверка существования: O(log n)
std::map<std::string, int> ages; // Пары ключ-значение, отсортированные по ключу
ages["Alice"] = 25; // Вставка/обновление: O(log n)
ages["Bob"] = 30;
std::cout << ages["Alice"]; // Доступ: O(log n)Неупорядоченные containers используют хеш-таблицы для ещё более быстрого поиска в среднем:
#include <unordered_map>
std::unordered_map<std::string, int> scores;
scores["player1"] = 100; // Вставка: O(1) в среднем
scores["player2"] = 200;
std::cout << scores["player1"]; // Доступ: O(1) в среднемИспользуйте vector, когда нужен быстрый произвольный доступ, list — для частых вставок в середину, map/set — когда нужны отсортированные данные, а unordered_map — когда критична скорость поиска и порядок не имеет значения.
Задание
ЛегкоДавайте создадим систему управления оценками студентов, которая демонстрирует, как разные контейнеры STL служат разным целям. Вы будете использовать несколько типов контейнеров для эффективной организации данных студентов, выбирая подходящий контейнер для каждой задачи.
Вы создадите два файла для организации кода:
GradeManager.h: DefineGradeManagerclass, которая использует несколько контейнеров STL для управления информацией о студентах.Ваш class должен использовать:
std::vector<std::string>для хранения имён студентов в порядке, в котором они были добавленыstd::map<std::string, int>для связывания имени каждого студента с его оценкойstd::set<int>для отслеживания всех уникальных оценок, которые были назначены
Implement следующие методы:
addStudent(const std::string& name, int grade): добавляет студента с его оценкой во все три контейнераgetGrade(const std::string& name): возвращает оценку для заданного имени студента, используя mapprintRoster(): выводит все имена студентов в порядке их добавления (из vector), каждое с новой строкиprintGrades(): выводит всех студентов с их оценками в алфавитном порядке (map обрабатывает это автоматически), в форматеname: gradeв каждой строкеprintUniqueGrades(): выводит все уникальные оценки в ascending порядке (set обрабатывает это), разделённые пробелами, а затем перевод строки
main.cpp: Прочитайте inputs и продемонстрируйте, как каждый тип контейнера служит отдельной цели.Прочитайте шесть inputs (каждый в отдельной строке):
- Имя первого студента
- Оценка первого студента (целое число)
- Имя второго студента
- Оценка второго студента (целое число)
- Имя третьего студента
- Оценка третьего студента (целое число)
Create
GradeManagerи добавьте всех трёх студентов. Затем продемонстрируйте различия в поведении контейнеров:- Выведите
Roster (insertion order):, затем вызовитеprintRoster() - Выведите
Grades (alphabetical):, затем вызовитеprintGrades() - Выведите
Unique grades:, затем вызовитеprintUniqueGrades() - Look оценку второго студента и выведите
<name>'s grade: <grade>
Например, для inputs Charlie, 85, Alice, 90, Bob, 85:
Roster (insertion order):
Charlie
Alice
Bob
Grades (alphabetical):
Alice: 90
Bob: 85
Charlie: 85
Unique grades:
85 90
Alice's grade: 90Обратите внимание, как vector сохраняет порядок insertion (Charlie, Alice, Bob), map автоматически сортирует по Key (Alice, Bob, Charlie), а set хранит только уникальные значения в отсортированном порядке (85 появляется один раз, а не два). Каждый тип контейнера особенно хорошо подходит для разных задач!
Попробуйте сами
#include <iostream>
#include <string>
#include "GradeManager.h"
using namespace std;
int main() {
// Считать входные данные для трёх студентов
string name1, name2, name3;
int grade1, grade2, grade3;
cin >> name1;
cin >> grade1;
cin >> name2;
cin >> grade2;
cin >> name3;
cin >> grade3;
// TODO: Создать объект GradeManager
// TODO: Добавить всех трёх студентов в GradeManager
// TODO: Print "Roster (insertion order):" and call printRoster()
// TODO: Print "Grades (alphabetical):" and call printGrades()
// TODO: Print "Unique grades:" and call printUniqueGrades()
// TODO: Найти оценку второго студента и вывести "<name>'s grade: <grade>"
return 0;
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыСборка и компиляция C++Заголовочные файлы и файлы исходного кодаПространства имен и область видимостиВведение в ООП на C++Классы и объектыУказатель 'this'Методы (функции-члены)Атрибуты (члены данных)Основы конструкторов и деструкторовИтоги — Простой калькулятор4Свойства классов
Члены экземпляра против статическихГеттеры и сеттерыКонстантные функции-членыКлючевое слово mutableСтатические методы и переменныеДружественные функции и классыИтоги — Менеджер банковских счетов7Наследование
Основы наследованияУровни доступа при наследованииПорядок вызова конструкторов и деструкторовПереопределение методовВиртуальные функции и VTableМножественное наследованиеВиртуальное наследованиеИтоги — Иерархия сотрудников10Обзор STL
Обзор и философия STLКонтейнеры STLИтераторыАлгоритмы STLФункторы и лямбда-выраженияИтоги: частота слов13Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonFactory и Abstract FactoryПаттерн BuilderПаттерн ObserverПаттерн Strategy2Управление памятью
Стек и кучаУказатели и ссылкиДинамическая память (new/delete)Умные указатели в C++RAII в C++Итоги — Менеджер динамического массива5Инкапсуляция
Спецификаторы доступа в C++Спецификаторы доступа: подробный разборСокрытие данныхStruct против ClassВложенные и внутренние классыИтоги — Система учета студентов8Полиморфизм
Полиморфизм компиляции и времени выполненияПерегрузка функцийВиртуальные функции: повторениеЧистые виртуальные функцииАбстрактные классыПроектирование интерфейсов на C++Dynamic Casting и RTTIИтоги: Калькулятор фигур11Продвинутые концепции ООП
Композиция против наследованияМиксины через CRTPИдиома PimplСтирание типовEnum Classes и строгая типизацияОбработка исключений в ООППользовательские иерархии исключений14Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикRAII как паттерн3Конструкторы и деструкторы
Конструктор по умолчаниюПараметризованный конструкторКонструктор копированияКонструктор перемещенияСписки инициализации конструктораДелегирующие конструкторыГлубокое погружение в деструкторыПравило трех / пяти / нуляПовторение — класс String6Перегрузка операторов
Введение в перегрузку операторовПерегрузка арифметических операторовПерегрузка операторов сравненияОператоры потоковПерегрузка оператора присваиванияПерегрузка операторов [] и ()Операторы преобразования типовИтоги — класс Matrix9Шаблоны
Шаблоны функцийШаблоны классовСпециализация шаблоновВариативные шаблоныОсновы SFINAE и Type TraitsИтоги — Обобщенный контейнерПотренируйтесь самостоятельно: Онлайн-компилятор C++