У чому різниця між std :: multimap <ключ, значення> та std :: map <ключ, std :: set <value>>


Відповіді:


51

Мультимапа зберігає пари (ключ, значення), де і ключ, і значення можуть з'являтися кілька разів.

map<key, set<value>>Буде зберігати тільки кожне значення один раз для конкретного ключа. Для цього йому доведеться мати можливість порівняти значення, а не лише ключі.

Це залежить від вашої програми, якщо значення, які порівнюють рівні, еквівалентні, чи ви хочете зберегти їх окремо. Можливо, вони містять поля, які відрізняються, але не беруть участі у порівнянні для набору.


5
Отже, std :: multimap <ключ, значення> схожий на std :: map <key, std :: multiset <value>>, різниця між ними полягає в тому, що пізніші значення сортуються. Це так?
大 宝剑

2
Ні, std::multimap<key, value>дозволяє одній і тій же клавіші з’являтися кілька разів, тоді як std::map<key, whatever>вимагає унікальності key.
Yixing Liu

74

A std::map- це асоціативний контейнер, який дозволяє вам мати унікальний ключ, пов'язаний зі значенням вашого типу. Наприклад,

void someFunction()
{
    typedef std::map<std::string, int> MapType;
    MapType myMap;

    // insertion
    myMap.insert(MapType::value_type("test", 42));
    myMap.insert(MapType::value_type("other-test", 0));

    // search
    auto it = myMap.find("test");
    if (it != myMap.end())
        std::cout << "value for " << it->first << " is " << it->second << std::endl;
    else
        std::cout << "value not found" << std::endl;
}

A std::multimapдорівнює a std::map, але ваші ключі вже не унікальні. Тому ви можете знайти цілий ряд предметів, а не просто знайти один унікальний предмет. Наприклад,

void someFunction()
{
    typedef std::multimap<std::string, int> MapType;
    MapType myMap;

    // insertion
    myMap.insert(MapType::value_type("test", 42));
    myMap.insert(MapType::value_type("test", 45));
    myMap.insert(MapType::value_type("other-test", 0));

    // search
    std::pair<auto first, auto second> range = myMap.equal_range("test");
    for (auto it = range.first; it != range.second; ++it)
        std::cout << "value for " << it->first << " can be " << it->second << std::endl;
}

Це std::setсхоже на std::map, але воно не зберігає ключ, пов'язаний зі значенням. Він зберігає лише тип ключа і гарантує вам, що він унікальний у наборі.

У вас також є те std::multiset, що дотримується тієї ж моделі.

Усі ці контейнери забезпечують доступ O (log (n)) з їх діапазоном find / jednaкий_.


6
У функції multimap цей рядок std::pair<auto first, auto second> range = myMap.equal_range("test");не працює, оскільки error: 'auto' not allowed in template argument. Використовуйте const auto range = myMap.equal_range("test")замість цього.
vancexu 02.03.14

2
mapType? Чи не повинен це бути MapType у рядку 4?
лолололол ол

не впевнений, хто був першим, але одне, очевидно, є копією іншого: cppbuzz.com/What-is-difference-between-map-and-multimap
idclev 463035818

1
ага, cppbuzz вишкрібає StackOverflow чи що ?, я написав цю відповідь сам багато років тому, коли ще щоденно кодував на c ++. І справді є помилка 4, спасибі @lololololol
typedef

1
(і їх копіювання / вставлення не вдалося, вони навіть не відображають типи в шаблоні std :: map statement: std :: map <std :: string, int>)
typedef

13
map::insert

Оскільки mapконтейнери не допускають повторення значень ключів, операція вставки перевіряє для кожного вставленого елемента, чи вже існує інший елемент у контейнері з тим самим значенням ключа, якщо так, елемент не вставляється і його відображене значення жодним чином не змінюється.

з іншого боку

multimap::insert 

можна вставити будь-яку кількість елементів за допомогою одного ключа.

http://www.cplusplus.com/reference/stl/map/
http://www.cplusplus.com/reference/stl/multimap/


Хороше посилання як на різницю, так і на те, як це працює внутрішньо. посилання
Rndp13

10

Останнє вимагає упорядкування значень (або за operator<допомогою функції порівняння), перше - ні.


Здавалося б, оператор <працює однаково як на карті, так і на мультимапі? en.cppreference.com/w/cpp/container/map/operator_cmp
johnbakers

Так, але моя відповідь стосувалася упорядкування значень. Припустимо, у вас є тип, Tякий як би не замовляє. Ви можете використовувати його для створення std::multimap<U, T>, але не можете використовувати для створення std::map<U, std::set<T> >.
Björn Pollex
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.