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
- Key-Value Pairs: Stores elements as pairs of keys and values, where keys are sorted.
- Multiple Values for Same Key: Unlike map, it allows duplicate keys.
- Ordered by Key: Elements are stored in ascending order by default based on keys.
- 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.