Ассоциативные контейнеры — мультимножество и мультиотображение.
По мультимножествам:
Разница между множествами и мультимножествами заключается в том, что множества содержат только уникальные элементы, а мультимножества могут содержать дубликаты. Возьмем код, работающий с множеством:
#include <iostream>
#include <set> // заголовочный файл множеств и мультимножеств
#include <iterator>
using namespace std;
int main()
{
set<char> mySet; // объявили пустое МНОЖЕСТВО
// добавляем элементы в множество
mySet.insert('I');
mySet.insert('n');
mySet.insert('f');
mySet.insert('i');
mySet.insert('n');
mySet.insert('i');
mySet.insert('t');
mySet.insert('y');
copy( mySet.begin(), mySet.end(), ostream_iterator<char>(cout, " "));
return 0;
}
Смотрим результат работы программы: I f i n t y
Как видно, это не совсем то, что мы вводили. Порядок ввода и реальный порядок элементов в множестве — разный, это связано с тем, что элементы множества автоматически сортируются. Еще одной очень важной деталью является то, что в множество не сохранились дубликаты, хотя дубликаты были при добавлении элементов в множество. Как видно в выводе программы, каждый элемент множества уникален.
Теперь вместо
set<char> mySet;
напишем
multiset<char> mySet;
Получаем:
#include <iostream>
#include <set> // заголовочный файл множеств и мультимножеств
#include <iterator>
using namespace std;
int main()
{
multiset<char> mySet; //объявление МУЛЬТИМНОЖЕСТВА
// добавляем элементы в множество
mySet.insert('I');
mySet.insert('n');
mySet.insert('f');
mySet.insert('i');
mySet.insert('n');
mySet.insert('i');
mySet.insert('t');
mySet.insert('y');
copy( mySet.begin(), mySet.end(), ostream_iterator<char>(cout, " "));
return 0;
}
Программа будет выдавать: I f i i n n t y
Результат другой, так как мультимножество может хранить дубликаты элементов, все введенные буквы сохранились. Все элементы отсортировались, как и в множестве. Следует запомнить то, что порядок ввода элементов в множество никак не влияет на порядок хранения в множестве. Автоматическая сортировка элементов в множествах накладывает определенные ограничения. Например, в множествах нельзя изменить значение какого-то элемента напрямую, так как это могло бы сломать сортировку. Поэтому, если нужно сделать это, сначала необходимо удалить старый элемент, а потом добавить новый.
По мультиотображениям:
Отображения и мультиотображения отличаются только тем, что последние могут содержать дубликаты, а первые — нет.
Ниже представлен код, который выводит год по заданному имени, используя отображение, и список годов, используя мультиотображение (для следующего билета).
#include <iostream>
#include <fstream>
#include <map>
#include <string>
using namespace std;
int main ()
{
fstream in ("input_task1.txt");
map<string,int> mp;
multimap<string,int> mmp;
/*заполнение map и multimap*/
while (!in.eof()){
string name;
in >> name;
int year;
in >> year;
mp.insert(map<string,int>::value_type(name,year));
mmp.insert(multimap<string,int>::value_type(name,year));
}
in.close();
/*вывести по заданному имени год (map)*/
string find_name_mp;
cout << "Enter name (for map) : ";
cin>>find_name_mp;
cout<<mp[find_name_mp]<<endl;
/*список годов (multimap)*/
string find_name_mmp;
cout<<"enter name (for multimap) : ";
cin>>find_name_mmp;
for (multimap<string,int>::iterator iter = mmp.find (find_name_mmp); iter != mmp.end() && iter->first == find_name_mmp ; ++iter){
cout<<iter->second <<endl;
}
return 0;
}
Содержимое входного файла:
Name1 2000
Name2 2001
Name3 2000
Name4 2004
Name2 2011
Name5 2005
Name6 2006
Name7 2007
Name2 2012
Name8 2000
Name9 2009
Результат работы программы:
Enter name (for map) : Name2 2001
Enter name (for multimap) : Name2 2001 2011 2012