multimap.
Если operator[] вам не подходит, т.е. другой способ найти ключ в map. Для этого можно использовать метод find.
map<string, string>::const_iterator p
= strMap.find('Thursday');
if (p != strMap.end())
cout << 'Thursday = ' << p->second << endl;
Но не забудьте, что при использовании multimap не гарантируется, что возвращаемый элемент будет первым элементом с ключом, равным искомому. Если нужен первый элемент, чей ключ не меньше определенного значения или не больше определенного значения, используйте lower_bound или upper_bound. lower_bound возвращает итератор, указывающий на первую пару ключ/значение, равную или большую, чем аргумент key_type. Другими словами, если ваш map содержит дни недели, как в примере 6.6, следующий код вернет итератор, который указывает на пару, содержащую 'Friday' и 'Freitag'.
p = strMap.lower_bound('Foo');
if (p != strMap.end())
cout << p->first << ' = ' << p->second << endl;
Это происходит благодаря тому, что первый ключ больше или равен 'Foo'. upper_bound работает аналогично, но с противоположным условием.
В начале этого обсуждения я упоминал, что элементы в map хранятся в отсортированном по ключам порядке, так что при переборе от begin до end каждый элемент будет «больше», чем предшествующий (а в multimap — больше или равен ему) Но при использовании более сложных ключей, чем string или числа, может потребоваться указать, как при вставке элементов в отображение следует сравнивать ключи.
По умолчанию ключи хранятся с помощью стандартного функтора less (объявленного в <functional>). less — это двоичная функция (принимает два аргумента одинакового типа), которая возвращает bool, указывающий на то, больше ли первый аргумент, чем второй, или нет. Другими словами, less(a, b) возвращает a < b. Если это не то, что вам требуется, создайте свой собственный функтор и объявите map с его помощью. Например, если в качестве ключа используется объект Person и каждый Person имеет имя и фамилию, то может потребоваться сравнивать фамилии и имена. Пример 6.7 показывает способ сделать это.
#include <iostream>
#include <map>
#include <string>
using namespace std;
class Person {
friend class PersonLessThan;
public:
Person(const string& first, const string& last) :
lastName_(last), firstName_(first) {}
// ...
string getFirstName() const {return(firstName_);}
string getLastName() const {return(lastName_);}
private:
string lastName_;
string firstName_;
};
class PersonLessThan {
public:
bool operator()(const Person& per1,
const Person& per2) const {
if (per1.lastName_ < per2. lastName_) // Сравнить фамилии,
return(true); // а затем
else if (per1.lastName_ == per2.lastName_) // имена
return(per1.firstName_ < per2.firstName_);
else
return(false);
}
};
int main() {
map<Person, string, PersonLessThan> personMap;
Person per1('Billy', 'Silly'),
per2('Johnny', 'Goofball'),
per3('Frank', 'Stank'),
реr4('Albert', 'Goofball');
personMap[per1] = 'cool';
personMap[per2] = 'not cool';
personMap[per3] = 'not cool';
personMap[per4] = 'cool';
for (map<Person, string, PersonLessThan>::const_iterator p =
personMap.begin(); p != personMap.end(); ++p) {
cout << p->first.getFirstName() << ' ' << p->first.getLastName()
<< ' is ' << p->second << endl;
}
}
map — это прекрасный способ хранить пары ключ/значение. После того как вы поймете поведение его частей, таких как operator[] и хранение данных (в виде объектов pair<Key, Value>), map предоставит простоту в использовании и высокую производительность.
Рецепт 6.7.
6.7. Использование хеш-контейнеров
Требуется сохранить ключи и значения, обеспечив постоянное время доступа к элементам, и не требуется хранения элементов в упорядоченном виде.
Используйте один из связанных с хешами контейнеров — hash_map или
