Exploring Maps and Multimaps in C++

Welcome to this lesson on Maps and Multimaps in C++, integral parts of the C++ Standard Library. These associative containers like std::map and std::multimap are used to store key-value pairs, maintaining an organized order of elements. Understanding these containers enhances your ability to manage data efficiently in C++.

Understanding std::map

The std::map is a key-value pair container that maintains order based on keys. It ensures each key is unique and directly employs a binary search tree to manage this order. Here's how you can create and utilize a std::map to track fruit quantities:

#include <iostream>
#include <map>

int main() {
    // Create a map with fruits as keys and their counts as values
    std::map<std::string, int> fruitMap = {
        {"banana", 3},
        {"apple", 4},
        {"pear", 1},
        {"orange", 2}
    };

    // Access and modify elements
    fruitMap["banana"] = 5; // Update the banana count

    // Insert a new fruit
    fruitMap.insert({"mango", 2});

    // Check if a key exists
    auto search = fruitMap.find("apple");
    if (search != fruitMap.end()) {
        // .end() provides an iterator to the position just after the last element
        std::cout << "Found 'apple' with count: " << search->second << std::endl;
    }

    // Iterate over the map
    for (const auto& [key, value] : fruitMap) {
        // 'key' refers to first and 'value' refers to second in key-value pair
        std::cout << key << ": " << value << std::endl;
    }

    return 0;
}

A std::map provides numerous methods to manage and traverse its elements efficiently. Here are some key operations:

  • insert: Adds a new key-value pair while maintaining sorted order.
  • find: Locates an element by its key and returns an iterator to it. If the element isn’t found, it returns end(), which is an iterator pointing just past the last element.
  • erase: Removes an element by its key or by iterator.
  • Iteration: Traverse the map's elements ordered by key, where the key is accessed via the first member and the value via second of the key-value pair.
Delving into std::multimap

The std::multimap deals with scenarios where keys can have multiple associated values. This is particularly useful when you need to store duplicate keys with differing values. Like std::map, std::multimap maintains an order based on keys but allows the same key to appear multiple times. Let's explore how you can leverage a std::multimap:

#include <iostream>
#include <map>

int main() {
    // Create a multimap with fruits as keys and their counts as values
    std::multimap<std::string, int> fruitMultiMap;
    fruitMultiMap.insert({"banana", 3});
    fruitMultiMap.insert({"apple", 4});
    fruitMultiMap.insert({"banana", 1});
    fruitMultiMap.insert({"orange", 2});

    // Find and output all values associated with "banana"
    auto range = fruitMultiMap.equal_range("banana");
    // range.first is the start iterator and range.second is the end iterator
    for (auto it = range.first; it != range.second; ++it) {
        std::cout << "banana: " << it->second << std::endl; // Output: banana: 3, banana: 1
    }

    // Iterate over the multimap
    for (const auto& [key, value] : fruitMultiMap) {
        std::cout << key << ": " << value << std::endl;
        // Output:
        // apple: 4
        // banana: 3
        // banana: 1
        // orange: 2
    }

    return 0;
}

Many methods are common between std::map and std::multimap, which include:

  • insert: Adds a key-value pair, allowing duplicate keys in std::multimap.
  • find: Searches for an element by its key and returns an iterator to the first pair with that key.
  • erase: Removes elements based on the key or iterator.

The equal_range method is particularly useful for accessing all elements with a given key, as it provides a pair of iterators marking the beginning and end of the matching range within the multimap. This is an important distinction because std::multimap doesn’t have an operator [] due to the possibility of duplicate keys, necessitating other methods for accessing all associated values. Understanding these shared and unique methods empowers you to effectively manipulate data with std::multimap, tailoring it more precisely to your application’s needs.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal