Home C++ C++ Standard Template Library (STL) multimap tutorial

C++ Standard Template Library (STL) multimap tutorial

The multimap in the C++ Standard Template Library (STL) is an associative container similar to map, but it allows multiple values for the same key.

It is useful in cases where a key might have multiple associated values and where the elements need to be stored in sorted order by key.

Key Features of multimap

  1. Key-Value Pairs: Stores elements as pairs of keys and values, where keys are sorted.
  2. Multiple Values for Same Key: Unlike map, it allows duplicate keys.
  3. Ordered by Key: Elements are stored in ascending order by default based on keys.
  4. Efficient Operations: Provides efficient insertion, deletion, and search operations based on keys.

Basic Syntax

#include <map>
using namespace std;

multimap<KeyType, ValueType> mmp;

Let’s explore the multimap container with various examples.

1. Initializing and Inserting Elements

A multimap can be initialized similarly to a map, but it allows inserting multiple elements with the same key.

#include <iostream>
#include <map>
using namespace std;

int main() {
    // Initialize an empty multimap
    multimap<string, int> scores;

    // Insert elements
    scores.insert(make_pair("Alice", 90));
    scores.insert(make_pair("Alice", 85));
    scores.insert(make_pair("Bob", 78));

    // Display elements
    cout << "Scores:" << endl;
    for (const auto &pair : scores) {
        cout << pair.first << ": " << pair.second << endl;
    }

    return 0;
}

Output:

Scores:
Alice: 90
Alice: 85
Bob: 78

2. Accessing Elements

multimap does not support the subscript operator [] for accessing elements because multiple values may be associated with the same key. Instead, you can use equal_range or find.

#include <iostream>
#include <map>
using namespace std;

int main() {
    multimap<string, int> scores = {{"Alice", 90}, {"Alice", 85}, {"Bob", 78}};

    // Access all values for a specific key
    auto range = scores.equal_range("Alice");
    cout << "Scores for Alice: ";
    for (auto it = range.first; it != range.second; ++it) {
        cout << it->second << " ";
    }
    cout << endl;

    return 0;
}

Output:

Scores for Alice: 90 85

3. Inserting Multiple Elements with the Same Key

You can insert multiple values with the same key, making multimap ideal for managing collections with duplicate keys.

#include <iostream>
#include <map>
using namespace std;

int main() {
    multimap<string, int> scores;

    // Insert multiple elements with the same key
    scores.insert(make_pair("Charlie", 70));
    scores.insert(make_pair("Charlie", 75));
    scores.insert(make_pair("Charlie", 80));

    cout << "Scores for Charlie:" << endl;
    for (const auto &pair : scores) {
        cout << pair.first << ": " << pair.second << endl;
    }

    return 0;
}

Output:

Scores for Charlie:
Charlie: 70
Charlie: 75
Charlie: 80

4. Removing Elements by Key

The erase function removes all elements for a specific key or elements at a specific iterator position.

#include <iostream>
#include <map>
using namespace std;

int main() {
    multimap<string, int> scores = {{"Alice", 90}, {"Alice", 85}, {"Bob", 78}};

    // Remove all values for the key "Alice"
    scores.erase("Alice");

    // Display remaining elements
    cout << "Remaining scores:" << endl;
    for (const auto &pair : scores) {
        cout << pair.first << ": " << pair.second << endl;
    }

    return 0;
}

Output:

Remaining scores:
Bob: 78

5. Counting Elements with a Specific Key

The count function returns the number of elements with a specific key.

#include <iostream>
#include <map>
using namespace std;

int main() {
    multimap<string, int> scores = {{"Alice", 90}, {"Alice", 85}, {"Bob", 78}};

    // Count the number of values for the key "Alice"
    cout << "Number of scores for Alice: " << scores.count("Alice") << endl;

    return 0;
}

Output:

Number of scores for Alice: 2

6. Finding Elements with a Specific Key

You can use find to get an iterator to the first element with a specific key or equal_range to get a range of elements for that key.

#include <iostream>
#include <map>
using namespace std;

int main() {
    multimap<string, int> scores = {{"Alice", 90}, {"Alice", 85}, {"Bob", 78}};

    // Using find() to get the first occurrence
    auto it = scores.find("Alice");
    if (it != scores.end()) {
        cout << "First score for Alice: " << it->second << endl;
    }

    return 0;
}

Output:

First score for Alice: 90

7. Iterating Over Elements

You can iterate over all elements in a multimap using a range-based for loop or an iterator.

#include <iostream>
#include <map>
using namespace std;

int main() {
    multimap<string, int> scores = {{"Alice", 90}, {"Alice", 85}, {"Bob", 78}};

    cout << "All scores:" << endl;
    for (auto it = scores.begin(); it != scores.end(); ++it) {
        cout << it->first << ": " << it->second << endl;
    }

    return 0;
}

Output:

All scores:
Alice: 90
Alice: 85
Bob: 78

8. Using equal_range to Access All Values for a Key

The equal_range function returns a pair of iterators that represent the range of elements with a specific key.

#include <iostream>
#include <map>
using namespace std;

int main() {
    multimap<string, int> scores = {{"Alice", 90}, {"Alice", 85}, {"Alice", 88}, {"Bob", 78}};

    // Using equal_range to get all scores for Alice
    auto range = scores.equal_range("Alice");
    cout << "Scores for Alice: ";
    for (auto it = range.first; it != range.second; ++it) {
        cout << it->second << " ";
    }
    cout << endl;

    return 0;
}

Output:

Scores for Alice: 90 85 88

9. Using multimap with a Custom Comparator

You can specify a custom comparator to define the order of keys in the multimap.

#include <iostream>
#include <map>
using namespace std;

struct DescendingOrder {
    bool operator()(const string &a, const string &b) const {
        return a > b;
    }
};

int main() {
    multimap<string, int, DescendingOrder> scores;

    // Insert elements
    scores.insert(make_pair("Alice", 90));
    scores.insert(make_pair("Bob", 78));
    scores.insert(make_pair("Charlie", 85));

    // Display elements in descending order of keys
    cout << "Scores in descending order:" << endl;
    for (const auto &pair : scores) {
        cout << pair.first << ": " << pair.second << endl;
    }

    return 0;
}

Output:

Scores in descending order:
Charlie: 85
Bob: 78
Alice: 90

10. Clearing the multimap

The clear function removes all elements from the multimap.

#include <iostream>
#include <map>
using namespace std;

int main() {
    multimap<string, int> scores = {{"Alice", 90}, {"Bob", 78}};

    cout << "Size before clear: " << scores.size() << endl;

    // Clear the multimap
    scores.clear();

    cout << "Size after clear: " << scores.size() << endl;

    return 0;
}

Output:

Size before clear: 2
Size after clear: 0

Summary Table of multimap Operations

Operation Code Example Description
Initialize multimap<string, int> mmp = {{“Alice”, 90}}; Creates a multimap with initial values
Insert element mmp.insert(make_pair(“Alice”, 85)); Inserts a key-value pair
Access elements by key auto range = mmp.equal_range(“Alice”); Accesses all values for a specific key
Remove elements by key mmp.erase(“Alice”); Removes all elements with a specific key
Count elements by key mmp.count(“Alice”); Counts occurrences of a specific key
Find element by key auto it = mmp.find(“Alice”); Finds the first occurrence of a specific key
Iterate for (auto &p : mmp) Iterates over all elements
Custom comparator multimap<string, int, CustomComparator> mmp; Creates a multimap with custom key ordering
Clear multimap mmp.clear(); Removes all elements

Complete Example

This example demonstrates initializing a multimap, inserting elements with duplicate keys, accessing and removing elements by key, counting occurrences, and iterating over elements.

#include <iostream>
#include <map>
using namespace std;

int main() {
    multimap<string, int> scores;

    // Insert elements
    scores.insert(make_pair("Alice", 90));
    scores.insert(make_pair("Alice", 85));
    scores.insert(make_pair("Bob", 78));
    scores.insert(make_pair("Alice", 88));

    // Access all values for "Alice"
    auto range = scores.equal_range("Alice");
    cout << "Scores for Alice: ";
    for (auto it = range.first; it != range.second; ++it) {
        cout << it->second << " ";
    }
    cout << endl;

    // Count occurrences of "Alice"
    cout << "Number of scores for Alice: " << scores.count("Alice") << endl;

    // Remove all scores for "Alice"
    scores.erase("Alice");

    // Display remaining scores
    cout << "Remaining scores:" << endl;
    for (const auto &pair : scores) {
        cout << pair.first << ": " << pair.second << endl;
    }

    return 0;
}

Sample Output:

Scores for Alice: 90 85 88 
Number of scores for Alice: 3
Remaining scores:
Bob: 78

Key Takeaways

  • multimap is an associative container that allows multiple values for the same key, storing elements in sorted order by key.
  • It’s ideal for scenarios where multiple values need to be associated with a single key.
  • Key functions include insert, equal_range, count, erase, and find.
  • Custom comparators allow for specific key sorting, and iterators provide flexible traversal and manipulation.

You may also like