Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP_Ekzamen.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
2.04 Mб
Скачать
  1. Асоціативні контейнери. Загальна характеристика.

Ассоциативные контейнеры

set

Упорядоченное множество уникальных элементов. При вставке/удалении элементов множества итераторы, указывающие на элементы этого множества, не становятся недействительными. Обеспечивает стандартные операции над множествами типа объединения, пересечения, вычитания. Тип элементов множества должен реализовывать оператор сравнения operator< или требуется предоставить функцию-компаратор. Реализован на основе самобалансирующего дерева двоичного поиска.

multiset

То же что и set, но позволяет хранить повторяющиеся элементы.

map

Упорядоченный ассоциативный массив пар элементов, состоящих из ключей и соответствующих им значений. Ключи должны быть уникальны. Порядок следования элементов определяется ключами. При этом тип ключа должен реализовывать оператор сравнения operator<, либо требуется предоставить функцию-компаратор.

multimap

То же что и map, но позволяет хранить несколько одинаковых ключей.

  1. Словники (map). Приклад словника.

Словари предназначены для хранения произвольного количества элементов, в виде пар "ключ-значение". Причем к "ключам" предъявляется требование уникальности. Словари обладают широкими возможностями доступа к произвольным элементам и незначительными накладными расходами на операцию добавления нового элемента. Если в словарь вставляется новое значение по существующему ключу, то оно затирает старое значение в паре "ключ-значение".

Класс словаря в STL определен под именем std::map<K, T>, в файле заголовка <map>. Ниже приводится пример объявления словаря, с целыми значениями в качестве ключей иFilm -- в качестве значения:

map<int, Film> films;

Эквивалент в Qt -- QMap<K, T>:

QMap<int, Film> films;

Наиболее естесственный способ заполнения словарей -- присваивать значение по заданному ключу:

films[4812] = Film("A Hard Day's Night", 85);

films[5051] = Film("Seven Days to Noon", 94);

films[1301] = Film("Day of Wrath", 105);

films[9227] = Film("A Special Day", 110);

films[1817] = Film("Day for Night", 116);

Итератор словаря предоставляет возможность доступа к паре "ключ-значение". Ключ извлекается с помощью (*it).first, а значение -- (*it).second:

map<int, Film>::const_iterator it = films.begin();

while (it != films.end()) {

cerr << (*it).first << ": "

<< (*it).second.title().ascii() << endl;

++it;

}

  1. Множини (set). Приклад множини.

Контейнер set, как уже было упомянуто, содержит множество элементов. Строго говоря, set обеспечивает следующую функциональность:

-- добавить элемент в рассматриваемое множество, при этом исключая возможность появления дублей;

-- удалить элемент из множества;

-- узнать количество (различных) элементов в контейнере;

-- проверить, присутствует ли в контейнере некоторый элемент.

Об алгоритмической эффективности контейнера set мы поговорим позже, вначале познакомимся с его интерфейсом.

set<int> s;

for(int i = 1; i <= 100; i++) {

s.insert(i); // добавим сто первых натуральных чисел

}

s.insert(42); // ничего не произойдёт ---

// элемент 42 уже присутствует в множестве

for(int i = 2; i <= 100; i += 2) {

s.remove(i); // удалим чётные числа

}

// set::size() имеет тип unsigned int

int N = int(s.size()); // N будет равно 50

У set нет метода push_back(). Это неудивительно: ведь такого понятия, как порядок элементов или индекс элемента, в set не существует, поэтому слово «back» здесь никак не применимо.

А раз уж у set нет понятия «индекс элемента», единственный способ просмотреть данные, содержащиеся в set, заключается в использовании итераторов:

set<int> S;

...

// вычисление суммы элементов множества S

int r = 0;

for(set<int>::const_iterator it = S.begin();

it != S.end(); it++) {

r += (*it);

}

Если вы пользуетесь GNU C++, то Traversing Macros будет весьма кстати. Показательный пример:

set< pair<string, pair< int, vector<int> > > SS;

...

int total = 0;

tr(SS, it) {

total += it->second.first;

}

Обратите внимание на синтаксис it->second.first. Ввиду того, что it является итератором, перед использованием его необходимо разыменовать. «Верным» синтаксисом было бы (*it).second.first. Однако, в C++ есть негласное правило, что если при описании некоторого объекта есть возможность обеспечить тождественное равенство конструкций (*it). и it->, то это следует сделать, дабы не вводить пользователей в заблуждение. Разработчики STL, конечно, позаботились об этом в случае с итераторами.

Основным преимуществом set перед vector является, несомненно, быстродействие. В основном это быстродействие проявляется при выполнении операции поиска. (При добавлении операция поиска также неявно присутствует, потому как дубли в set не допускаются). Однако, с операцией поиска в set/map есть существенный нюанс.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]