std::unordered_map


STL Container: std::unordered_map

std::unordered_map is a C++ container that stores key-value pairs in an unordered fashion, providing average-case constant-time complexity (O(1)) for insertions, deletions, and lookups. Unlike std::map, which stores elements in a sorted order, std::unordered_map is implemented using a hash table, making it highly efficient for scenarios where the order of elements does not matter, but fast access to elements is crucial.

Key Characteristics of std::unordered_map

Basic Operations on std::unordered_map

Example 1: Basic Usage of std::unordered_map

include <iostream>
include <unordered_map>

int main() {
    std::unordered_map<std::string, int> ageMap;

    // Insertion
    ageMap["Alice"] = 30;
    ageMap["Bob"] = 25;
    ageMap["Charlie"] = 35;

    // Accessing elements
    std::cout << "Alice's age: " << ageMap["Alice"] << std::endl;

    // Lookup
    if (ageMap.find("Bob") != ageMap.end()) {
        std::cout << "Bob is in the map." << std::endl;
    }

    // Deletion
    ageMap.erase("Charlie");

    // Iterating over the map
    std::cout << "People in ageMap:" << std::endl;
    for (const auto& pair : ageMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }

    return 0;
}

Explanation:

Example 2: Custom Hash Function

You can define custom hash functions for complex key types, such as custom classes or structures.

include <iostream>
include <unordered_map>
include <string>

struct Person {
    std::string firstName;
    std::string lastName;

    bool operator==(const Person& other) const {
        return firstName == other.firstName && lastName == other.lastName;
    }
};

// Custom hash function for Person
struct PersonHash {
    std::size_t operator()(const Person& p) const {
        return std::hash<std::string>()(p.firstName) ^ std::hash<std::string>()(p.lastName);
    }
};

int main() {
    std::unordered_map<Person, int, PersonHash> personAgeMap;

    // Insertion
    personAgeMap[{"Alice", "Smith"}] = 30;
    personAgeMap[{"Bob", "Brown"}] = 25;

    // Lookup
    Person searchPerson = {"Alice", "Smith"};
    if (personAgeMap.find(searchPerson) != personAgeMap.end()) {
        std::cout << "Found Alice Smith, age: " << personAgeMap[searchPerson] << std::endl;
    }

    return 0;
}

Explanation:

Example 3: Handling Collisions

In std::unordered_map, collisions occur when different keys produce the same hash value. The map handles these collisions internally using chaining or open addressing.

include <iostream>
include <unordered_map>

int main() {
    // A custom hash function that could cause many collisions
    struct BadHash {
        std::size_t operator()(int x) const {
            return x % 10;  // Not a very good hash function
        }
    };

    std::unordered_map<int, std::string, BadHash> myMap;

    myMap[10] = "Ten";
    myMap[20] = "Twenty";  // Likely to collide with 10

    // Inserting and accessing elements
    std::cout << "10: " << myMap[10] << std::endl;
    std::cout << "20: " << myMap[20] << std::endl;

    return 0;
}

Explanation:

Use Cases for std::unordered_map

Summary

std::unordered_map is a powerful tool when you need fast, efficient key-value storage without concern for the order of elements. It's particularly useful in applications where quick access to data is essential, and where you might be working with large datasets.

Previous Page | Course Schedule | Course Content