- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
C++. Сборник рецептов - Д. Стефенс
Шрифт:
Интервал:
Закладка:
Для отображения ключей (string) на значения (любой тип, который подчиняется семантике значений) используйте стандартный контейнер map, объявленный в <map>. Пример 6.6 показывает, как это делается.
Пример 6.6. Создание отображения строк
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<string, string> strMap;
strMap["Monday"] = "Montag";
strMap["Tuesday"] = "Dienstag";
strMap["Wednesday"] = "Mittwoch";
strMap["Thursday"] = "Donnerstag";
strMap["Friday"] = "Freitag";
strMap["Saturday"] = "Samstag";
// strMap.insert(make_pair("Sunday", "Sonntag"));
strMap.insert(pair<string, string>("Sunday", "Sonntag"));
for(map<string, string>::iterator p = strMap.begin();
p != strMap.end(); ++p) {
cout << "English: " << p->first
<< German: " << p->second << endl;
}
cout << endl;
strMap.erase(strMap.find("Tuesday"));
for (map<string, string>::iterator p = strMap.begin();
p ! = strMap.end(); ++p) {
cout << "English: " << p->first
<< ", German: " << p->second << endl;
}
}
Обсуждениеmap — это ассоциативный контейнер, который отображает ключи на значения, предоставляет логарифмическую сложность вставки и поиска и постоянную сложность удаления одного элемента. Обычно разработчики используют отображение для хранения объектов по их ключам типа string. Именно это делает пример 6.6. В этом случае отображаемый тип является строкой, но он может быть почти чем угодно.
Отображение объявляется вот так.
map<typename Key, // Тип ключа
typename Value, // Тип значения
typename LessThanFun = std::less<Key>, // Функция/функтор,
// используемые для сортировки
typename Alloc = std::allocator<Key> > // Распределитель памяти
Key и Value — это типы ключа и связанного значения, которые хранятся в отображении. LessThanFun — это функция или функтор, который принимает два аргумента и возвращает истину, если первый меньше, чем второй. По умолчанию используется стандартный функтор less. Alloc — это распределитель памяти, и по умолчанию используется стандартный.
Использование map довольно просто. Объявите тип ключа и значения вот так.
map<string, string> strMan;
В результате будет создан map, в котором и ключ, и значение имеют тип string. С помощью operator[] поместите в отображение объекты, что интуитивно и легко читаемо.
strMap["Monday"] = Montag";
strMap["Tuesday"] = "Dienstag";
strMap["Wednesday"] = "Mittwoch"; // ...
В результате в map будут вставлены элементы с индексом (например, "Monday") в качестве ключа и правым операндом в качестве значения. Они хранятся в порядке, определяемом параметром шаблона LessThanFun, и если он не указан, то map использует std::less<Key>.
Чтобы получить значения из map, используйте operator[] в правой части присвоения, как здесь.
wedInGerman = strMap["Wednesday"];
В манере всех стандартных контейнеров значение, связанное с ключом "Wednesday", с помощью operator= копируется в объект wedInGerman.
operator[] — это удобный способ вставки или обновления элементов или получения значений из map, но он имеет побочный эффект, который может оказаться неожиданным. Строго говоря, operator[k] возвращает ссылку на значение, ассоциированное с k — независимо от того, существует ли k в map или нет. Если k уже находится в map, то возвращается ассоциированное с ним значение. Если нет, то k вставляется, а затем используется конструктор по умолчанию, который создает объект значения для этого ключа. Чтобы сделать это более понятным, рассмотрим, что делает следующий код.
map<string, string> mapZipCodes; // Сейчас здесь ноль элементов
string myZip = mapZipCodes["Tempe"]; // В map пока что нет элементов,
// но чему теперь равно count()?
Что находится в myZip и сколько теперь элементов в mapZipCodes? Так как operator[] вставляет указанный ключ, если он не существует, myZip содержит пустую строку, а в mapZipCodes содержится один элемент. Это может оказаться нежелательно, но независимо от вашего желания помните, что operator[] не является const-методом: всегда есть вероятность того, что он изменит состояние map, добавив узел.
Метод insert предоставляет альтернативный метод добавления пар в отображение, insert выполняет строгую вставку, а не вставку/обновление, как operator[]. При использовании map (но не multimap, который может содержать дублирующиеся ключи) insert, если ключ уже существует, не делает ничего. По сравнению с ним operator[], если ключ уже существует, заменяет значение объекта для этого ключа на новое.
Но синтаксис вставки требует несколько большей работы, чем operator[], и он связан с тем, как map хранит данные. Рассмотрим строку из примера 6.6.
strMap.insert(std::make_pair("Sunday", "Sonntag"));
map хранит пары ключ/значение в объекте pair, pair — это простой вспомогательный шаблон класса (объявленный в <utility> и включенный в <map>), который хранит два значения двух типов. Чтобы объявить pair из двух string, сделайте так.
pair<string, string> myPair;
Первый и второй элементы в pair доступны по открытым членам first и second. При использовании для доступа к элементам map оператора operator[] обычно работать с pair не приходится, но в случае со многими другими методами это придется делать, так что следует знать, как создавать и использовать объекты pair. Например, итераторы разыменовываются в простые объекты pair, так что при их использовании, как это делается в примере 6.6, следует знать, как получить ключ и его значение.
for (map<string, string> iterator p = strMap.begin();
p != strMap.end(); ++p)
cout << "English: " << p->first
<< ", German: " << p->second << endl;
Ключ хранится в first, а значение хранится в second.
Однако это не объясняет, почему я использовал make_pair. make_pair — это вспомогательный шаблон функции, который создает объект pair на основе двух переданных в него аргументов. Некоторые предпочитают этот подход вызову конструктора pair, так как шаблон класса не может догадаться о типах своих аргументов, в то время как шаблон функции может. Таким образом, эти две строки кода функционально эквивалентны.
strMap.insert(std::make_pair("Sunday", "Sonntag"));
strMap.insert(std::pair<string, string>("Sunday", "Sonntag"));
map не допускает наличия дублирующихся ключей. Если требуется разрешить дублирование ключей, следует использовать multimap, который является map, разрешающим наличие несколько одинаковых ключей. Его интерфейс идентичен map, но поведение методов в необходимых случаях отличается. В табл. 6.1 приведен перечень методов, которые есть в одном, но отсутствуют в другом, и пояснения различий в поведении общих методов, map и multimap содержат несколько typedef, которые описывают различные значения, хранящиеся в них. В табл. 6.1 они используются следующим образом:
key_type
Это тип ключа. В string map, объявленном как map<string, MyClass*>, key_type должен быть string.
mapped_type
Это тип значения, на которое отображается ключ. В string map, объявленном как map<string, MyClass*>, mapped_type должен быть MyClass*.
value_type
Это тип объекта, содержащего ключ и значение, которой, применительно к map и multimap, является pair<const key_type, mapped_type>.
Табл. 6.1. map и multimap
Метод map, multimap или оба Поведение T& operator[] (const key_type& k) map Возвращает ссылку на объект значения, сохраненный с ключом k. Если k в map отсутствует, то он добавляется, а объект значения создается с помощью конструктора по умолчанию iterator insert(const value_type& v) pair<iterator, bool> insert(const value_type& v) Оба Первая версия вставляет v в multimap и возвращает итератор, который указывает на вставленную пару pair. Вторая версия вставляет v и map при условии, что в map еще не содержится ключа, равного v. Возвращаемая pair содержит итератор который указывает на вставленную pair, если произошла вставка, и bool, указывающий, была ли вставка успешной iterator find(const key_type& k) Оба Возвращает итератор или const_iterator, который указывает на mapped_type, соответствующий k. В multimap не гарантируется, что возвращаемый итератор будет указывать на первое значение, соответствующее k. Если ключа, равного k, нет, то возвращаемый итератор равен end()Также табл 6.1 показывает разницу в поведении между map и multimap.

