C++ unordered_set
In C++, the std::unordered_set
is an associative container that stores unique elements in an unordered fashion using a hash table. Unlike std::set
, which maintains elements in sorted order, unordered_set
does not guarantee any specific order for its elements. It offers constant-time average complexity (O(1)) for insertion, deletion, and lookup operations, making it efficient for use cases where you do not require the order of elements but need fast access.
This container is part of the C++ Standard Library, provided in the <unordered_set>
header, and is best suited when you need to check for membership or perform other operations like insertion and deletion quickly, based on a unique set of keys.
The syntax to declare an unordered_set
is:
std::unordered_set<ElementType> unordered_set_name;
Where:
ElementType
: The type of the element stored in the set (e.g., int
, std::string
).You can also specify a custom hash function and comparison function:
std::unordered_set<ElementType, Hash, Compare> unordered_set_name;
Where:
Hash
: A function or function object used for hashing the keys.Compare
: A custom comparison function for comparing keys (though not typically needed as unordered_set
uses a default comparator).
#include <iostream>
#include <unordered_set>
int main() {
// Declare an unordered set with int elements
std::unordered_set<int> uset;
// Insert elements into the unordered set
uset.insert(10);
uset.insert(20);
uset.insert(30);
uset.insert(40);
uset.insert(50);
// Displaying the elements of the unordered set
for (const auto& element : uset) {
std::cout << element << std::endl;
}
return 0;
}
Output:
10
20
30
40
50
Note: The order in which the elements are displayed is not guaranteed because unordered_set
does not maintain any specific order.
You can insert elements into an unordered set using the insert()
method:
uset.insert(60); // Insert the element 60 into the unordered set
You can search for an element in the unordered set using the find()
method. This returns an iterator to the element if found, or unordered_set::end()
if the element is not present.
auto it = uset.find(30); // Search for the element 30
if (it != uset.end()) {
std::cout << "Found: " << *it << std::endl;
} else {
std::cout << "Element not found!" << std::endl;
}
You can remove an element by value or by iterator.
uset.erase(20); // Removes the element with value 20
auto it = uset.find(40);
uset.erase(it); // Removes the element pointed to by the iterator
You can check whether a specific element exists in the unordered set using the count()
method. Since the set stores unique elements, this method returns either 1 (if the element is found) or 0 (if not).
std::cout << "Count of 20: " << uset.count(20) << std::endl; // Output: 0
std::cout << "Count of 30: " << uset.count(30) << std::endl; // Output: 1
You can check the size of the unordered set and whether it is empty using the size()
and empty()
methods:
std::cout << "Size of unordered set: " << uset.size() << std::endl;
std::cout << "Is unordered set empty? " << (uset.empty() ? "Yes" : "No") << std::endl;
You can remove all elements from the unordered set using the clear()
method:
uset.clear(); // Removes all elements from the unordered set
You can iterate over the elements of an unordered set using an iterator or a range-based for loop:
for (auto it = uset.begin(); it != uset.end(); ++it) {
std::cout << *it << std::endl;
}
Example 2: Using Range-Based For Loop
for (const auto& element : uset) {
std::cout << element << std::endl;
}
If you're using a custom type as the element of the unordered set, you need to define a custom hash function.
Suppose you have a custom class Person
and want to use it as an element in an unordered set.
#include <iostream>
#include <unordered_set>
#include <string>
class Person {
public:
std::string name;
int age;
Person(std::string name, int age) : name(name), age(age) {}
bool operator==(const Person& other) const {
return name == other.name && age == other.age;
}
};
struct PersonHash {
size_t operator()(const Person& p) const {
return std::hash<std::string>()(p.name) ^ std::hash<int>()(p.age); // Combine hashes of name and age
}
};
int main() {
std::unordered_set<Person, PersonHash> uset;
uset.insert(Person("Alice", 30));
uset.insert(Person("Bob", 25));
for (const auto& person : uset) {
std::cout << person.name << " (" << person.age << ")" << std::endl;
}
return 0;
}
Output:
Alice (30)
Bob (25)
std::unordered_set
unordered_set
offers O(1) average time complexity for insertion, deletion, and lookup operations, making it highly efficient for large datasets.std::set
, it ensures that all elements are unique, so there are no duplicates.unordered_set
provides a fast and memory-efficient solution.std::unordered_set
Use std::unordered_set
when: