- •Практическое занятие 1. Работа с последовательными контейнерами вектор и двусторонняя очередь.
- •Последовательный контейнер vector
- •Немодифицирующие операции
- •Операции присваивания
- •Операции с итераторами вектора
- •Втавка и удаление элементов
- •Последовательный контейнер deque
- •Практическое занятие 2. Работа со списками в stl Двунаправленный список
- •Немодифицирующие операции
- •Операции присваивания
- •Прямой доступ к элементам списка
- •Операции с итераторами списка
- •Операции вставки и удаления элементов списка
- •Специальные модифицирующие операции
- •Однонаправленный список
- •Конструкторы и деструктор
- •Немодифицирующие операции
- •Операции вставки и удаления элементов
- •Практическое занятие 3. Ассоциативные контейнеры: множество и мультимножество
- •Специальные операции поиска
- •Рекомендуемая литература
Работа с STL
Москва 2017
Практикум содержит материалы к практическим занятиям. Приведены необходимые теоретические сведения, примеры решения типовых задач и задания для самостоятельной работы. Практикум предназначен для слушателей, обучающихся по специальности «Информационная безопасность телекоммуникационных систем».
Практическое занятие 1. Работа с последовательными контейнерами вектор и двусторонняя очередь.
STL-контейнер – это параметризованный класс, представляемый шаблоном классов и имеющий набор шаблонных параметров для реализации того или иного конкретного класса, максимально приспособленного для решения практической задачи. Объект такого параметризованного класса пригоден для включения других объектов. Разные контейнеры обеспечивают различную эффективность тех или иных операций, так что необходимо разумно подходить к выбору наиболее подходящего к ситуации контейнерного класса. Контейнеры обладают рядом преимуществ перед классическими массивами языка С/С++, решающими ту же задачу. Большинство контейнеров поддерживают динамическое изменение собственного размера, так что нет необходимости заранее беспокоиться о выделении достаточного объёма памяти и дальнейшем его перераспределении в случае необходимости. Информация о числе элементов в контейнере всегда доступна, её не нужно хранить отдельно, как это было в случае массивов. Для контейнеров доступен более широкий набор операций, тогда как для массивов возможно лишь чтение или запись элементов по заданному индексу.
Рассмотрим следующую задачу: Задан массив. Найти максимальное значение среди элементов массива и добавить его в качестве нового элемента в конец массива.
Приведем листинги программ для решения данной задачи:
С использованием динамического массива C/C++:
//Листинг 25.1
#include<iostream>
using namespace std;
int main()
{
int n;
cin >> n;
//создание динамического массива
int *mas = new int[n];
//заполнение массива
for (int i = 0; i < n; ++i)
mas[i] = i;
//нахождение максимума
int max = mas[0];
for (int i = 1; i < n;++i)
if (max < mas[i]) max = mas[i];
//добавление элемента в массив:
//1.выделяем дин.память для n+1 элемента
int *mas1 = new int[n + 1];
//2.поэлементно копируем
for (int i = 0; i < n; ++i)
mas1[i] = mas[i];
//3.присваиваем значения n+1-му элементу
mas1[n] = max;
//4. очищаем дин.память
delete[] mas;
//вывод содержимого массива на экран
for (int i = 0; i < n+1; ++i)
cout << mas1[i] << " ";
cout << endl;
return 0;
}
С использованием контейнера STL vector и алгоритма max_element():
//Листинг 25.2
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
//создание вектора
vector<int> vec(n);
//заполнение вектора
//используем операцию индексации
for (int i = 0; i < n; ++i)
vec[i] = i;
//нахождение максимума
//используем алгоритм STL max_element
int max = *max_element(vec.begin(),
vec.end());
//добавление элемента в вектор:
vec.push_back(max);
//вывод содержимого вектора на экран
//используем итераторы
for (auto ptr = vec.begin(); ptr!=vec.end();
++ptr)
cout << *ptr << " ";
cout << endl;
return 0;
}
Последовательный контейнер vector
Вектор (vector) – это самый простой последовательный контейнер, реализованный в памяти в виде динамического массива, элементы которого хранятся в определённом порядке и занимают непрерывную область памяти с возможностью расширения с конца. В силу такой организации (рис.25.1) vector обеспечивает произвольный доступ к своим элементам.
При работе с контейнерами вместо указателей используются итераторы, выполняющие те же функции, но организованные в виде встроенных классов, что позволяет обеспечить корректную работу со всеми контейнерами. Для итераторов перегружены основные операции, имитирующие их поведение как обычных указателей. Одной из особенностей итераторов является соглашение, по которому, при указании интервала, итератор конца показывает не на последний элемент, а на элемент, лежащий после последнего, даже если физически таковой отсутствует. Такой интервал называется полуоткрытым и обозначается: [begin,end).
Рис. 25.1. Структура контейнера vector
Итераторы вектора являются итераторами произвольного доступа (т. е. позволяют передвигаться по контейнеру в обоих направлениях на произвольное количество элементов), поэтому к вектору применимы все алгоритмы STL.
Операции вставки и удаления элементов в конце вектора происходят с высоким быстродействием, однако при их выполнении внутри вектора быстродействие существенно снижается, поскольку все элементы в последующих позициях приходится перемещать на новое место.
Для использования данного контейнера необходимо подключить заголовок <vector>.
Операции с векторами рассмотрим по группам, составив соответствующие таблицы: конструкторы и дестуктор, немодифицирующие операции, операции сравнения, операции присваивания, доступ к элементам вектора, итераторы вектора, вставка и удаление элементов.
Таблица 25.1
Конструкторы, деструктор
Операция |
Назначение |
vector<T> v |
Создаёт пустой вектор v для элементов типа Т |
vector<T> v(n) |
Создаёт вектор v из n элементов, равных Т() |
vector<T> v2(v1) |
Создаёт копию вектора v1 |
vector<T> v2=v1 |
Создаёт копию вектора v1 |
vector<T> v2(n,elem) |
Создаёт вектор v из n копий elem типа Т |
vector<T> v2(begin,end) |
Создает вектор из элементов интервала [begin, end) любого контейнера, в том числе и из элементов простого массива |
vector<T> v(initlist) |
Создает вектор, инициа-лизированный элементами списка инициализации initlist (стандарт С++ 11) |
vector<T> v=initlist |
Создает вектор, инициа-лизированный элементами списка инициализации initlist (стандарт С++ 11) |
v.~vector() |
Уничтожает все элементы и освобождает память |
Здесь Т – тип данных элементов вектора.
Таблица 25.2
