std::map
std::map
is an associative container in the C++ Standard Template Library (STL) that stores key-value pairs in a sorted order based on the keys. 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::map<std::string, int> ages;
// Inserting elements
ages["Alice"] = 30;
ages.insert({"Bob", 25});
ages.insert(std::make_pair("Charlie", 35));
// Accessing elements
std::cout << "Alice's age: " << ages["Alice"] << std::endl;
// Checking if a key exists
if (ages.find("David") == ages.end()) {
std::cout << "David is not in the map" << std::endl;
}
// Iterating through the map
for (const auto& pair : ages) {
std::cout << pair.first << " is " << pair.second << " years old" << std::endl;
}
// Size of the map
std::cout << "Number of entries: " << ages.size() << std::endl;
// Removing an element
ages.erase("Bob");
return 0;
}
map
with string keys and integer values is created[]
operator, insert()
, and std::make_pair
[]
operator is used for direct access to valuesfind()
is used to check if a key existssize()
returns the number of elementserase()
removes an element by its key#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::map<std::string, int, DescendingOrder> scores;
scores["Alice"] = 95;
scores["Bob"] = 89;
scores["Charlie"] = 92;
scores["David"] = 78;
for (const auto& pair : scores) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
DescendingOrder
is defined for string keysmap
is initialized with this custom comparatorstd::map
map
with Custom Objects#include <iostream>
#include <map>
#include <string>
class Student {
public:
Student(const std::string& name, int age) : name(name), age(age) {}
std::string getName() const { return name; }
int getAge() const { return age; }
private:
std::string name;
int age;
};
// Custom comparator for Student objects
struct StudentComparator {
bool operator()(const Student& a, const Student& b) const {
return a.getName() < b.getName();
}
};
int main() {
std::map<Student, double, StudentComparator> studentGrades;
studentGrades[Student("Alice", 20)] = 3.8;
studentGrades[Student("Bob", 22)] = 3.5;
studentGrades[Student("Charlie", 21)] = 3.9;
for (const auto& pair : studentGrades) {
std::cout << pair.first.getName() << " (Age: " << pair.first.getAge()
<< "): GPA = " << pair.second << std::endl;
}
return 0;
}
Student
class is defined with name and age attributesStudentComparator
is created to sort Student
objects by namemap
uses Student
objects as keys and double
as valuesmap
#include <iostream>
#include <map>
#include <string>
#include <vector>
// Function to print the course roster
void printCourseRoster(const std::map<std::string, std::map<std::string, std::vector<int>>>& university) {
for (const auto& dept : university) {
std::cout << "Department: " << dept.first << std::endl;
for (const auto& course : dept.second) {
std::cout << " Course: " << course.first << ", Students: ";
for (int studentId : course.second) {
std::cout << studentId << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
}
}
int main() {
// Map structure: Department -> (Course -> List of Student IDs)
std::map<std::string, std::map<std::string, std::vector<int>>> university;
// Adding data
university["Computer Science"]["Programming 101"] = {1001, 1002, 1003};
university["Computer Science"]["Data Structures"] = {1002, 1004, 1005};
university["Mathematics"]["Calculus I"] = {1001, 1005, 1006};
university["Mathematics"]["Linear Algebra"] = {1003, 1004, 1006};
// Print the course roster
printCourseRoster(university);
// Adding a new student to a course
university["Computer Science"]["Programming 101"].push_back(1007);
// Checking if a department exists
std::string deptToCheck = "Physics";
if (university.find(deptToCheck) == university.end()) {
std::cout << deptToCheck << " department does not exist." << std::endl;
}
return 0;
}
printCourseRoster
function shows how to iterate through this nested structurefind
method is used to check for the existence of a key (department in this case)Performance: While map
provides good performance for most operations, consider using std::unordered_map
for faster lookup times if sorting is not required.
Memory Usage: map
typically uses more memory than a simple array due to its tree structure.
Key Immutability: Once a key-value pair is inserted, the key cannot be modified. To change a key, you must remove the old pair and insert a new one.
Value Modification: Values can be modified directly through iterators or using the []
operator.
Default-Constructed Values: Using the []
operator on a non-existent key will insert a default-constructed value.
std::map
is a versatile container in C++ for storing key-value pairs in a sorted order. Key points to remember:
std::map
is particularly useful in situations where you need to:
- Implement dictionaries or lookup tables
- Maintain sorted associations between keys and values
- Represent hierarchical data
- Perform range-based queries on keys
Understanding when to use std::map
versus other containers like std::unordered_map
or std::vector
is crucial for writing efficient and clear C++ code in various application domains. Its ordered nature makes it ideal for scenarios where both fast lookup and sorted traversal are important.