Оператор взятия индекса является простейшим способом извлечения элемента. Например:
// mapstring,int word_count;
int count = word_count[ "wrinkles" ];
Однако этот способ работает так, как надо, только при условии, что запрашиваемый ключ действительно содержится в отображении. Иначе оператор взятия индекса поместит в отображение элемент с таким ключом. В данном случае в word_count занесется пара
string( "wrinkles" ), 0
Класс map предоставляет две операции для того, чтобы выяснить, содержится ли в нем определенное значение ключа.
count(keyValue): функция-член count() возвращает количество элементов с данным ключом. (Для отображения оно равно только 0 или 1). Если count() вернула 1, мы можем смело использовать индексацию:
int count = 0;
if ( word_count.count( "wrinkles" ))
count = word_count[ "wrinkles" ];
*
find(keyValue): функция-член find() возвращает итератор, указывающий на элемент, если ключ найден, и итератор end() в противном случае. Например:
int count = 0;
mapstring,int::iterator it = word_count.find( "wrinkles" );
if ( it != word_count.end() )
count = (*it).second;
*
Значением итератора является указатель на объект pair, в котором first содержит ключ, а second – значение. (Мы вернемся к этому в следующем подразделе.)
6.12.3. Навигация по элементам отображения
После того как мы построили отображение, хотелось бы распечатать его содержимое. Мы можем сделать это, используя итератор, начальное и конечное значение которого получают с помощью функций-членов begin() и end(). Вот текст функции display_map_text():
void
display_map_text( mapstring,loc* *text_map )
{
typedef mapstring,loc* tmap;
tmap::iterator iter = text_map-begin(),
iter_end = text_map-end();
while ( iter != iter_end )
{
cout "word: " (*iter).first " (";
int loc_cnt = 0;
loc *text_locs = (*iter).second;
loc::iterator liter = text_locs-begin(),
liter_end = text_locs-end();
while (liter != liter_end ) {
if ( loc_cnt )
cout ',';
else ++loc_cnt;
cout '(' (*liter).first
',' (*liter).second ')';
++liter;
}
cout ")\n";
++iter;
}
cout endl;
}
Если наше отображение не содержит элементов, данная функция не нужна. Проверить, пусто ли оно, можно с помощью функции-члена size():
if ( text_map-size() )
display_map_text( text_map );
Но более простым способом, без подсчета элементов, будет вызов функции-члена empty():
if ( ! text_map-empty() )
display_map_text( text_map );
6.12.4. Словарь
Вот небольшая программа, иллюстрирующая построение отображения, поиск в нем и обход элементов. Здесь используются два отображения. Первое, необходимое для преобразования слов, содержит два элемента типа string. Ключом является слово, которое нуждается в специальной обработке, а значением – слово, заменяющее ключ. Для простоты мы задали пары ключ/значение непосредственно в тексте программы (вы можете модифицировать программу так, чтобы она читала их из стандартного ввода или из файла). Второе отображение используется для подсчета произведенных замен. Текст программы выглядит следующим образом:
#include map
#include vector
#include iostream
#include string
int main()
{
map string, string trans_map;
typedef map string, string ::value_type valType;
// первое упрощение:
// жестко заданный словарь
trans_map.insert( va1Type( "gratz", "grateful" ));
trans_map.insert( va1Type( "'em", "them" ));
trans_map.insert( va1Type( "cuz", "because" ));
trans_map.insert( va1Type( "nah", "no" ));
trans_map.insert( va1Type( "sez", "says" ));
trans_map.insert( va1Type( "tanx", "thanks" ));
trans_map.insert( va1Type( "wuz", "was" ));