std::multimap
std::multimap
is an associative container in the C++ Standard Template Library (STL) that stores key-value pairs in a sorted order based on the keys, allowing multiple elements with the same key. Like std::map
, it is typically implemented as a balanced binary search tree (usually a red-black tree), providing logarithmic time complexity for insertion, deletion, and search operations.
#include <iostream>
#include <map>
#include <string>
int main() {
std::multimap<std::string, int> studentScores;
// Inserting elements
studentScores.insert({"Alice", 85});
studentScores.insert({"Bob", 90});
studentScores.insert({"Alice", 92}); // Another score for Alice
studentScores.insert({"Charlie", 88});
studentScores.insert({"Bob", 95}); // Another score for Bob
// Iterating through the multimap
for (const auto& pair : studentScores) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
// Counting entries for a specific key
std::string name = "Alice";
std::cout << "Number of scores for " << name << ": "
<< studentScores.count(name) << std::endl;
// Finding all scores for a specific student
auto range = studentScores.equal_range(name);
std::cout << name << "'s scores: ";
for (auto it = range.first; it != range.second; ++it) {
std::cout << it->second << " ";
}
std::cout << std::endl;
// Size of the multimap
std::cout << "Total number of scores: " << studentScores.size() << std::endl;
return 0;
}
multimap
with string keys (student names) and integer values (scores) is createdinsert()
methodcount()
is used to find the number of entries for a specific keyequal_range()
returns a pair of iterators representing the range of elements with a given keysize()
returns the total number of elements in the multimap#include <iostream>
#include <map>
#include <string>
// Custom comparator for descending order of keys
struct DescendingOrder {
bool operator()(const std::string& a, const std::string& b) const {
return a > b;
}
};
int main() {
std::multimap<std::string, int, DescendingOrder> fruitInventory;
fruitInventory.insert({"Apple", 100});
fruitInventory.insert({"Banana", 150});
fruitInventory.insert({"Cherry", 75});
fruitInventory.insert({"Apple", 120}); // Another entry for Apple
fruitInventory.insert({"Banana", 130}); // Another entry for Banana
for (const auto& pair : fruitInventory) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
DescendingOrder
is defined for string keysmultimap
is initialized with this custom comparatorstd::multimap
multimap
for Grouping and Analysis#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
// Structure to represent a sale
struct Sale {
std::string product;
double amount;
std::string date;
};
// Function to print sales summary
void printSalesSummary(const std::multimap<std::string, Sale>& sales) {
for (const auto& category : sales) {
std::cout << "Category: " << category.first << std::endl;
double total = 0.0;
std::vector<double> amounts;
for (auto it = sales.lower_bound(category.first);
it != sales.upper_bound(category.first); ++it) {
total += it->second.amount;
amounts.push_back(it->second.amount);
}
std::cout << " Total Sales: $" << total << std::endl;
if (!amounts.empty()) {
std::cout << " Average Sale: $" << total / amounts.size() << std::endl;
std::cout << " Highest Sale: $" << *std::max_element(amounts.begin(), amounts.end()) << std::endl;
}
std::cout << std::endl;
}
}
int main() {
std::multimap<std::string, Sale> salesData;
// Inserting sales data
salesData.insert({"Electronics", {"Laptop", 1200.00, "2023-01-15"}});
salesData.insert({"Clothing", {"T-Shirt", 25.99, "2023-01-16"}});
salesData.insert({"Electronics", {"Smartphone", 800.00, "2023-01-17"}});
salesData.insert({"Clothing", {"Jeans", 59.99, "2023-01-18"}});
salesData.insert({"Electronics", {"Headphones", 150.00, "2023-01-19"}});
salesData.insert({"Clothing", {"Dress", 89.99, "2023-01-20"}});
// Print sales summary
printSalesSummary(salesData);
return 0;
}
multimap
to group sales data by categorySale
struct represents individual salesmultimap
with the category as the keyprintSalesSummary
function demonstrates how to analyze grouped data:lower_bound
and upper_bound
to iterate over sales in each categorymultimap
can be used for data grouping and analysismultimap
#include <iostream>
#include <map>
#include <string>
void printMultimap(const std::multimap<std::string, int>& mm) {
for (const auto& pair : mm) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
std::cout << "Size: " << mm.size() << std::endl << std::endl;
}
int main() {
std::multimap<std::string, int> wordCount;
// Inserting elements
wordCount.insert({"apple", 1});
wordCount.insert({"banana", 2});
wordCount.insert({"apple", 3});
wordCount.insert({"cherry", 4});
wordCount.insert({"banana", 5});
std::cout << "Initial multimap:" << std::endl;
printMultimap(wordCount);
// Removing a single element by key
std::string keyToRemove = "cherry";
wordCount.erase(keyToRemove);
std::cout << "After removing '" << keyToRemove << "':" << std::endl;
printMultimap(wordCount);
// Removing all elements with a specific key
keyToRemove = "banana";
auto removed = wordCount.erase(keyToRemove);
std::cout << "After removing all '" << keyToRemove << "' (removed " << removed << " elements):" << std::endl;
printMultimap(wordCount);
// Removing a single element by iterator
auto it = wordCount.find("apple");
if (it != wordCount.end()) {
wordCount.erase(it);
std::cout << "After removing one 'apple' entry:" << std::endl;
printMultimap(wordCount);
}
return 0;
}
multimap
erase(key)
removes all elements with the specified keyerase(iterator)
removes the element at the specified positionerase
function returns the number of elements removedPerformance: While multimap
provides good performance for most operations, consider using std::unordered_multimap
for faster lookup times if sorting is not required.
Memory Usage: Like map
, multimap
typically uses more memory than simpler data structures due to its tree structure.
No Direct Access: Unlike map
, multimap
does not provide the []
operator for direct access, as keys are not unique.
Iteration Order: Elements are always traversed in the sorted order defined by the comparison function.
Value Modification: Values can be modified through iterators, but keys cannot be modified directly to maintain the correct ordering.
std::multimap
is a powerful container in C++ for storing multiple key-value pairs with the same key in a sorted order. Key points to remember:
equal_range
, lower_bound
, and upper_bound
for efficient range operationsstd::multimap
is particularly useful in situations where you need to:
- Store multiple values associated with a single key in a sorted structure
- Implement one-to-many relationships
- Group and analyze data by categories
- Maintain a sorted collection of elements with potential duplicates
Understanding when to use std::multimap
versus other containers like std::map
, std::unordered_multimap
, or std::vector
is crucial for writing efficient and clear C++ code in various application domains. Its ability to handle multiple values per key while maintaining a sorted order makes it a versatile choice for many complex data management scenarios.