Контейнер 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++11to 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!!!
вот как у меня получилось:
// map_main.cpp // #include <iostream> #include <map> #include <string> using std::endl; using std::cout; using std::map; using std::pair; using std::string; int main() { map<string, int> myFirstMap; myFirstMap.insert(pair<string, int>("Mother", 37)); myFirstMap.insert(pair<string, int>("Father", 40)); // map явно инициализирована myFirstMap.insert(pair<string, int>("Brother", 15) ); myFirstMap.insert( pair<string, int>("Sister", 20)); // вывод явно инициализированой map на экран for(auto it = myFirstMap.begin(); it != myFirstMap.end(); ++it) { cout << it->first << " : " << it->second << endl; } 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; }eagle_vik
писало error: Ошибка C2552: инициализация не агрегированных данных с помощью списка инициализации не допускается…
так вот