Мы рассмотрели простой пример использования map<> для подсчёта вхождения отдельных литер в текст. Для этой цели мы использовали контейнер map<>. Но библиотека STL нам предоставляет и другой (близкий) тип контейнера — это multimap<>, который допускает наличие многих элементов (pair<>) в своём составе с одинаковыми значениями ключей.
Естественно, что основные правила функционирования multimap<> изменятся (по сравнению с map<>). Для такого контейнера будут следующие отличия в поведении:
- Содержит упорядоченные пары <ключ,значение>, где ключ и значение могут принадлежать к произвольным типам; 
- Элементы с любыми значениями ключа не должны быть уникальными, в упорядоченной последовательности элементов (по ключу) такие эквивалентные элементы представлены, как разные элементы, и располагаются они друг за другом; 
- Поскольку ключи могут совпадать, то операция добавления новой пары в таблицу (метод insert()) всегда успешна. Поэтому нет смысла возвращать результат такой операции: возвращаемое значение — void; 
- Поскольку теперь в контейнере может находиться много элементов с равными ключами, то вводится дополнительный метод count(). Он получает параметром значение ключа, возвращает число вхождений элементов, имеющих такой ключ, в контейнер; 
- Операции удаления (метод erase()) с указанием ключа удаляемого элемента удаляет все сразу элементы с совпадающими ключами; 
Посмотрим как multimap<> справится с предыдущей задачей. Вот текстовые файлы для тестирования программы:
| 30 Brother_And_Sister | 11 Humpty-Dumpty | 34 Jabberwock | 
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include <iostream>  #include <sstream>  #include <map>  using namespace std; int main(int argc, char **argv) {  multimap< char, int > alphabet;  while (cin) {  string line;  getline(cin, line);  if (line.empty()) continue;  istringstream ist(line);  char let;  while ((let = ist.get()) && let != EOF)  alphabet.insert(pair< char, int >(let, 1));  }  cout << "alphabet size = " << alphabet.size() << endl;  for (char c = 'a'; c <= 'z'; c++)  cout << c << "(" << alphabet.count(c) << ") ";  cout << endl;  alphabet.erase('a');  cout << "alphabet size = " << alphabet.size() << endl;  for (char c = 'a'; c <= 'z'; c++)  cout << c << "(" << alphabet.count(c) << ") ";  cout << endl;  cout << "alphabet size = " << alphabet.size() << endl; } | 
Как и в предыдущем примере, используется несколько громоздкий ввод символов из потока, содержащего текст во много строк. Это связано с тем, что а). хотелось бы читать и символы пробела тоже как символы, а не как разделители и б). можно было бы просто последовательно читать символы из cin с последующим исключением переводов строки. Но в показанном варианте хотелось бы сохранить независимость от используемой операционной системы (различие так называемого DOS и UNIX перевода строки). В остальной части код стал много короче и проще.
Результат того, что мы получили, показан ниже (рядом повторено для сравнения то же действие, выполняемое map<>):


Обратим внимание на то, как единичным оператором удаления alphabet.erase( ‘a’ ) мы удалили из таблиц 38 элементов, определяющихся ключом ‘a’. Откуда взялся размер size() в 696 элементов?
(Показанная форма команды wc вычисляет в операционной системе Linux число строк в файле. Команда ls выводит длину файла, т.е. число отдельных байт, символов в файле. В Windows вы можете попытаться добиться некоторого подобного результата используя команду dir.)
Если мы из общего числа символов (длины в байтах) вычтем число строк (переводов строк) в файле, то мы и получим эту цифру: 726 – 30 = 696. Таким образом, для каждого символа входного потока был создан отдельный элемент таблицы, например, с ключом ‘s’ было 39 таких элементов.
Всё, ранее сказанное относительно контейнера map<> (кроме алгоритма помещения и выборки) в полной мере относится и к multimap<>, например, требование сравнимости ключей и то, как определить или переопределить операцию сравнения.
