Exploring unordered_map in C++
The unordered_map
in C++ is a powerful container that stores elements in the form of key-value pairs. It provides efficient average time complexity for insertion, deletion, and search operations, making it ideal for scenarios where fast lookups are required.
Introduction to unordered_map
An unordered_map
is implemented using a hash table, which allows for fast access to elements based on their keys. Keys in an unordered_map
are unique, and the elements are not stored in any particular order, unlike map
which maintains elements in a sorted order based on keys.
Key Operations
Let's dive into the fundamental operations you can perform with unordered_map
: insertion, search, and deletion.
1. Insertion
Inserting elements into an unordered_map
is straightforward. If the key already exists, its associated value is updated. If the key does not exist, a new key-value pair is added.
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<std::string, int> umap;
// Inserting key-value pairs
umap["apple"] = 2;
umap["banana"] = 3;
umap.insert({"cherry", 5});
// Display contents after insertion
for (const auto& pair : umap) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
In the example above:
umap["apple"] = 2;
inserts or updates the key "apple" with the value2
.umap.insert({"cherry", 5});
inserts a new key-value pair "cherry" with the value5
.
2. Search
Searching for an element in an unordered_map
involves using the find
function, which returns an iterator to the element if found, or umap.end()
if not found.
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<std::string, int> umap;
umap["apple"] = 2;
umap["banana"] = 3;
// Searching for a key
auto it = umap.find("banana");
if (it != umap.end()) {
std::cout << "Found " << it->first << " with value " << it->second << std::endl;
} else {
std::cout << "banana not found" << std::endl;
}
return 0;
}
Here:
umap.find("banana");
searches for the key "banana" inumap
.If found (
it != umap.end()
), it prints the key and value; otherwise, it indicates that the key was not found.
3. Deletion
To remove an element from an unordered_map
, you can use the erase
function, either by key or by iterator.
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<std::string, int> umap;
umap["apple"] = 2;
umap["banana"] = 3;
// Deleting a key
umap.erase("apple");
// Display contents after deletion
for (const auto& pair : umap) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
umap.erase("apple");
removes the key "apple" and its associated value fromumap
.
Using auto
with unordered_map
The auto
keyword simplifies the declaration of iterators, especially in complex types like unordered_map
.
auto& pair : umap
allows iterating over each key-value pair inumap
without explicitly declaring the type of the iterator.auto it = umap.find("banana");
declaresit
as an iterator that points to the key "banana" inumap
.
Useful Functions in unordered_map
Here are some useful functions provided by unordered_map
:
insert
: Inserts a key-value pair into the map.find
: Searches for a key and returns an iterator to it.erase
: Removes an element by key or by iterator.size
: Returns the number of elements in the map.empty
: Checks if the map is empty.clear
: Removes all elements from the map.
Functions of unordered_map
1. insert
The insert
function inserts a key-value pair into the unordered_map
. If the key already exists, the insertion is ignored.
Example:
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<std::string, int> umap;
// Insert using insert function
umap.insert({"apple", 2});
umap.insert({"banana", 3});
umap.insert({"cherry", 5});
// Display contents
for (const auto& pair : umap) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
2. find
The find
function searches for a key in the map and returns an iterator pointing to the key-value pair if found, or umap.end()
if not found.
Example:
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<std::string, int> umap = {{"apple", 2}, {"banana", 3}, {"cherry", 5}};
// Searching for a key
auto it = umap.find("banana");
if (it != umap.end()) {
std::cout << "Found " << it->first << " with value " << it->second << std::endl;
} else {
std::cout << "banana not found" << std::endl;
}
return 0;
}
3. erase
The erase
function removes an element from the map by key or by iterator.
Example:
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<std::string, int> umap = {{"apple", 2}, {"banana", 3}, {"cherry", 5}};
// Erasing a key
umap.erase("apple");
// Display contents after deletion
for (const auto& pair : umap) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
4. size
The size
function returns the number of key-value pairs in the map.
Example:
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<std::string, int> umap = {{"apple", 2}, {"banana", 3}, {"cherry", 5}};
// Get the size of the map
std::cout << "Size of umap: " << umap.size() << std::endl;
return 0;
}
5. empty
The empty
function checks if the map is empty (i.e., contains no elements) and returns true
if empty, false
otherwise.
Example:
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<std::string, int> umap;
// Check if map is empty
if (umap.empty()) {
std::cout << "Map is empty" << std::endl;
} else {
std::cout << "Map is not empty" << std::endl;
}
return 0;
}
6. clear
The clear
function removes all elements from the map.
Example:
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<std::string, int> umap = {{"apple", 2}, {"banana", 3}, {"cherry", 5}};
// Clear all elements
umap.clear();
// Check if map is empty after clearing
if (umap.empty()) {
std::cout << "Map is empty" << std::endl;
} else {
std::cout << "Map is not empty" << std::endl;
}
return 0;
}
7. operator[]
The operator[]
allows accessing or inserting elements using a key. If the key exists, it returns a reference to its associated value; if not, it inserts the key with a default value (0
for int
).
Example:
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<std::string, int> umap;
// Inserting or updating using operator[]
umap["apple"] = 2;
umap["banana"] = 3;
// Accessing using operator[]
std::cout << "Value of apple: " << umap["apple"] << std::endl;
return 0;
}
Iterating Through unordered_map
To iterate through all elements in an unordered_map
, you can use a range-based for loop or iterator-based loop.
Example (Range-based for loop):
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<std::string, int> umap = {{"apple", 2}, {"banana", 3}, {"cherry", 5}};
// Using range-based for loop to iterate
for (const auto& pair : umap) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
Example (Iterator-based loop):
#include <iostream>
#include <unordered_map>
int main() {
std::unordered_map<std::string, int> umap = {{"apple", 2}, {"banana", 3}, {"cherry", 5}};
// Using iterator to iterate
for (auto it = umap.begin(); it != umap.end(); ++it) {
std::cout << it->first << ": " << it->second << std::endl;
}
return 0;
}
Conclusion
Understanding the functions provided by unordered_map
allows you to effectively manage key-value pairs in C++. These functions provide essential operations like insertion, search, deletion, size checking, and clearing, making unordered_map
a versatile choice for handling associative arrays.
By mastering these concepts and examples, you'll be equipped to utilize unordered_map
efficiently in your C++ projects, ensuring fast and efficient data retrieval and manipulation.