Пример 6.7. Использование собственного функтора сортировки
#include
#include
#include
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 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::const_iterator p =
personMap.begin(); p != personMap.end(); ++p) {
cout << p->first.getFirstName() << " " << p->first.getLastName()
<< " is " << p->second << endl;
}
}
map— это прекрасный способ хранить пары ключ/значение. После того как вы поймете поведение его частей, таких как operator[]и хранение данных (в виде объектов pair), mapпредоставит простоту в использовании и высокую производительность.
Смотри также
Рецепт 6.7.
6.7. Использование хеш-контейнеров
Проблема
Требуется сохранить ключи и значения, обеспечив постоянное время доступа к элементам, и не требуется хранения элементов в упорядоченном виде.
Решение
Используйте один из связанных с хешами контейнеров — hash_mapили hash_set. Однако помните, что они не входят в число стандартных контейнеров, определяемых стандартом С++, а представляют собой расширения, включаемые большинством реализаций стандартной библиотеки. Пример 6.8 показывает, как использовать hash_set.
Пример 6.8. Хранение строк в hash_set
#include
#include
#include
int main() {
hash_set hsString;
string s = "bravo";
hsString.insert(s);
s = "alpha";
hsString.insert(s);
s = "charlie";
hsString.insert(s);
for (hash set::const_iterator p = hsString.begin();
p != hsString.end(); ++p)
cout << *p << endl; // заметьте, что здесь не гарантируется хранение
// в упорядоченном виде
}
Обсуждение
Контейнеры, основанные на хешах, — это популярные во всех языках структуры данных, и прискорбно, что стандарт C++ не требует их реализации. Однако если требуется использовать хеш-контейнер, то не все потеряно: высока вероятность, что используемая вами реализация стандартной библиотеки содержит hash_mapи hash_set, но тот факт, что они не стандартизованы, означает, что их интерфейсы могут отличаться от одной реализации стандартной библиотеки к другой. Я опишу хеш-контейнеры, которые поставляются в составе реализации стандартной библиотеки STLPort.
STLPort — это свободно распространяемая переносимая реализация стандартной библиотеки, существующая уже довольно длительное время и предоставляющая хеш-контейнеры. При использовании другой библиотеки интерфейс может быть другим, но общая идея будет той же самой.
Главной особенностью хеш-контейнеров (называемых во многих книгах по ассоциативными хеш-контейнерами) является то, что они в общем случае предоставляют постоянное время поиска, вставки и удаления элементов, а в худшем случае эти операции имеют линейное время. Ценой постоянного времени выполнения этих операций является то, что в хеш-контейнере они хранятся в неупорядоченном виде, как в map.
Посмотрите на пример 6.8. Использование хеш-контейнера (в данном случае hash_set) довольно просто — объявите его как большинство других контейнеров и начните вставлять в него элементы.
hash_set hsString; // hash_set строк
string s = "bravo";
hsString.insert(s); // Вставка копии s
Использование hash_mapаналогично, за исключением того, что требуется, как минимум, указать типы данных используемых ключей и значений. Это аналогично map.
hash_map
hmStrings; // Отображение строк на строки
string key = "key";
string val = "val";
hmStrings[key] = val;
Это только основы использования хеш-контейнеров. Также имеется набор параметров шаблона, которые позволяют указать используемую хеш-функцию, функцию, проверяющую ключи на эквивалентность, и объект, используемый для распределения памяти. Я опишу их немного позже.
Читать дальше