Контейнер map
, очень похож на остальные контейнеры, такие как vector, list, deque, но с небольшим отличием. В этот контейнер можно помещать сразу два значения. Если у Вас когда-то была мечта написать свой словарь, то лучше чем map
, вам альтернативы не найти. И так, что же такое этот map
, давай рассмотрим более подробнее на примере:
#include <iostream> #include <map> //подключили библиотеку для работы с map using namespace std; int main() { map <string,int> myFirstMap = {{ "Mother", 37 }, { "Father", 40 },///map явно инициализирована { "Brother", 15 }, { "Sister", 20 }}; ///вывод явно инициализированной map на экран for (auto it = myFirstMap.begin(); it != myFirstMap.end(); ++it) { cout << it->first << " : " << it->second << endl; } char c; map <char,int> mySecondMap; for (int i = 0,c = 'a'; i < 5; ++i,++c) { mySecondMap.insert ( pair<char,int>(c,i) ); } ///вывод не явно инициализированной map на экран for (auto it = mySecondMap.begin(); it != mySecondMap.end(); ++it) { cout << (*it).first << " : " << (*it).second << endl; } return 0; }
Пример выполнения программы:
Во 2 строке мы подключили библиотеку для работы с map
. В строках 7-10 происходит явное объявление map
, это объявление ничем не отличается от объявления векторов, массивов, за исключением того, что объявляются сразу два типа переменных (первый тип – string
, второй тип — int
). В кавычках объявляются строки, а через запятую соответствующее строке число. Если бы написали вместо string
тип char
, то объявление было-бы таким:
map <char,int> myFirstMap= {{ 'm', 37 }, { 'f', 40 }, { 'b', 15 }, { 's', 20 }};
Нужно добавить, что map
можно использовать в виде ассоциативного массива. Массива который позволяет в себе хранить пару вида («ключ», «значение»), а так-же добавлять и удалять пары по ключу. У нас в роли ключа выступает тип string
, а в роли значения тип int
.
Осуществление вывода ничем не отличается от вывода тех же векторов. Обратите внимание, что вывод осуществляется в алфавитном порядке, а заполнение map в строках 7-10, нет. Контейнер map
сам выполняет сортировку по алфавиту. В строках 13-16 осуществляется вывод с помощью итератора it
. Итератор it
сначала указывает на начало map
и с каждой новой итерацией увеличивается, пока не достигнет конца map
. Самое интересное располагается в строке 15. Запись вида it->first
означает, что it
при первой итерации указывает на строку Mother
, потом на Father
и так далее до конца цикла, соответственно, запись вида it->second
означает, что it
при первой итерации указывает на число 37, потом на 40 и так далее.
В строке 19 мы объявили map mySecondMap
. В строках 20-23 заполняем его. Строка 22 содержит функцию map::insert()
. Которая вставляет элементы в map
. Запись вида pair<char,int>(c,i)
означает, что в map
помещаются две переменные типа char
и int
(первая – char
, вторая — int
), где типу char
соответствует переменная c
, а типу int
соответствует переменная i
. В строке 20 при каждой новой итерации наши переменные будут увеличиваться, т. е. сначала i=0,
c=a
, при следующей итерации i=1
, c=b
и т. д. В строке 28 показан альтернативный вывод map
с помощью указателей. У map
есть один небольшой недостаток, она не может содержать два одинаковых значения, но multimap
решает эту проблему, пример:
#include <iostream> #include <map> using namespace std; int main() { map <char,int> myFirstMap;///объявили map ///заполняем myFirstMap myFirstMap.insert ( pair<char,int>('a',10) ); myFirstMap.insert ( pair<char,int>('a',20) ); myFirstMap.insert ( pair<char,int>('a',10) ); cout << "myFirstMap contains:\n"; for (auto it = myFirstMap.begin(); it != myFirstMap.end(); ++it)///вывод на экран { cout << it->first << " : " << it->second << endl; } multimap <char,int> myFirstMultimap;///объявили multimap ///заполняем myFirstMultimap myFirstMultimap.insert ( pair<char,int>('a',10) ); myFirstMultimap.insert ( pair<char,int>('a',20) ); myFirstMultimap.insert ( pair<char,int>('a',10) ); cout << "myFirstMultimap contains:\n"; for (auto it = myFirstMultimap.begin(); it != myFirstMultimap.end(); ++it)///вывод на экран { cout << it->first << " : "<< it->second << endl; } return 0; }
Пример выполнения программы:
Работа программы должна быть полностью понятна, так, что на ней останавливаться не будем. Как видите контейнер myFirstMap
может содержать только одно не повторяющееся значение <char, int>
, а multimap
нет. С этой целью и был создан контейнер multimap
. Multimap
ничем не отличается от map
, за исключением того, что в нем можно хранить повторяющиеся элементы. Думаю, для начала достаточно.
Комментарии
TonyVCLCSA .
Не желает со string работать.
error C2679: бинарный «<<«: не найден оператор, принимающий правый операнд типа «const std::string» (или приемлемое преобразование отсутствует)
с типами char и int все работает.
Rick Petrev
npavelFax
Официальная работа в интернете
Vitaliy Sobol
Add
-std=c++11
to your compiler flags (with gcc/icc/clang) if you want to useauto
(and other C++11 features)…from-> http://stackoverflow.com/questions/22880431/iterate-through-unordered-map-cVitaliy Sobol
NaikoN
eagle_vik Не могу ответить на Ваш вопрос, т.к. не использую MVS2012 Ultimate Edition.
eagle_vik
Серёжа а что используешь?? Code::Blocks? Я поставил уже себе Visual Studio 2013 Express, и всё работает отлично, видимо в 2012-й студии не полностью реализован стандарт был!!! Уже всё пашет!
NaikoN
eagle_vik, да я использую Сode::blocks :)
eagle_vik
Первый пример не работает!!! (MVS2012 Ultimate Edition)
Порылся на форумах, написано что даже со стандартом С++11 необходимо каждый раз инициализировать через insert!!!
вот как у меня получилось:
eagle_vik
писало error: Ошибка C2552: инициализация не агрегированных данных с помощью списка инициализации не допускается…
так вот