Использование библиотеки STL
Ассоциативный контейнер map
Теперь мы можем перейти от set к map. «Введение в map для чайников» могло бы выглядеть следующим образом:
map<string, int> M; M["One"] = 1; M["Two"] = 2; M["Many"] = 7; int x = M["One"] + M["Two"]; if(M.find("Five") != M.end()) { M.erase("Five"); }
Очень просто, не так ли?
На самом деле, map очень похож на set, за исключением того, что вместо элементов map хранит пары элементов <ключ, значение>. Поиск при этом осуществляется только по ключу. Крайне приятно наличие оператора обращения по «индексу» (operator []).
Для того, чтобы просмотреть содержимое map, необходимо использовать итераторы. Удобнее всего это делать при помощи нашего макроса tr. Следует помнить, что итератор указывает не на элемент key, а на pair<key, value>:
map<string, int> M; ... M["one"] = 1; M["two"] = 2; M["google"] = 1e100; ... // найдём сумму всех значений --- т.е. всех правых частей // пар <string, int> int r = 0; tr(M, it) { r += it->second; // (*it).first == [string], (*it).second == [int] }Как и в случае с set, элементы map хранятся упорядоченными по ключу. Поэтому не следует при работе с map::iterator модифицировать it->first: если вы нарушите правила упорядочивания элементов в map, за последствия никто отвечать не возьмётся.
В остальном контейнер map по интерфейсу практически эквивалентен контейнеру set.
Также важно помнить, что operator [] при обращении к несуществующему элементу в map создаст его. Новый элемент при этом будет инициализирован нулём (либо конструктором по умолчанию, если это не тривиальный тип данных). Данная особенность map может быть удобной, потому как выполнять операции с элементами можно не задумываясь об их присутствии в map. Существенным моментом является то, что operator [] не является константным (то есть может изменить объект, для которого вызван), поэтому им нельзя пользоваться, если map передан как const reference. Используйте map::find(element):
void f(const map<string, int>& M) { if(M["the meaning"] == 42) { // Так нельзя! M передан как const reference } if(M.find("the meaning") != M.end() && M.find("the meaning")->second == 42) { // А можно именно так cout << "Don't Panic!" << endl; } }