C++ Sets
Understanding set containers for unique sorted elements
🎯 What are Sets?
Sets are associative containers that store unique elements in sorted order. They automatically maintain elements in ascending order and prevent duplicates, making them perfect for membership testing and sorted collections.
#include <set>
#include <iostream>
using namespace std;
int main() {
set<int> mySet = {30, 10, 50, 10}; // 10 appears only once
for (int x : mySet) {
cout << x << " "; // Output: 10 30 50 (sorted, unique)
}
return 0;
}
Types of Sets
set
Unique elements in sorted order
set<int> uniqueSet;
multiset
Allows duplicate elements, sorted
multiset<int> duplicateSet;
unordered_set
Unique elements, no specific order
unordered_set<int> hashSet;
unordered_multiset
Duplicates allowed, no order
unordered_multiset<int> hashMultiSet;
🔹 Basic Set Operations
Sets in C++ are associative containers that store unique, sorted elements, enabling efficient membership
tests and mathematical operations. The standard std::set provides logarithmic-time search,
insertion, and deletion. Basic operations include insert, find, erase, and
iteration in sorted order. Sets are ideal for maintaining a collection of distinct items, removing duplicates, or
performing set operations like union and intersection. Their ordered nature distinguishes them from unordered
counterparts, making them suitable for scenarios where sorted traversal or range-based queries are required.
#include <set>
#include <iostream>
using namespace std;
int main() {
set<int> mySet;
// Insert elements
mySet.insert(50);
mySet.insert(20);
mySet.insert(30);
mySet.insert(20); // Duplicate - won't be added
cout << "Set size: " << mySet.size() << endl; // Size: 3
// Check if element exists
if (mySet.find(30) != mySet.end()) {
cout << "30 found in set" << endl;
}
// Count occurrences (always 0 or 1 for set)
cout << "Count of 20: " << mySet.count(20) << endl; // Count: 1
// Print all elements (automatically sorted)
cout << "Elements: ";
for (int x : mySet) {
cout << x << " ";
}
return 0;
}
Output:
30 found in set
Count of 20: 1
Elements: 20 30 50
🔹 Multiset Example
A multiset (std::multiset) extends the set by allowing duplicate elements while maintaining
automatic sorting. It stores multiple equivalent keys, each counted separately, and supports all
standard set operations. This is useful in scenarios like scoreboards, frequency counting, or priority queues where
duplicates are meaningful. Elements are always traversed in sorted order, and operations like
equal_range or count help manage duplicate groups. Multisets provide the ordered benefits
of sets with the flexibility to handle non-unique data, filling a specific niche in the STL container ecosystem.
#include <set>
#include <iostream>
using namespace std;
int main() {
multiset<int> mset;
// Insert duplicates
mset.insert(10);
mset.insert(20);
mset.insert(10);
mset.insert(30);
mset.insert(20);
cout << "Multiset size: " << mset.size() << endl; // Size: 5
cout << "Count of 10: " << mset.count(10) << endl; // Count: 2
cout << "Elements: ";
for (int x : mset) {
cout << x << " ";
}
// Remove one occurrence of 10
mset.erase(mset.find(10));
cout << "\nAfter removing one 10: ";
for (int x : mset) {
cout << x << " ";
}
return 0;
}
Output:
Count of 10: 2
Elements: 10 10 20 20 30
After removing one 10: 10 20 20 30
🔹 Unordered Set Example
Unordered sets (std::unordered_set) use hash tables for average constant-time operations,
trading ordering for speed. They store unique elements but do not maintain any specific order. This
makes them ideal for fast lookups, insertions, and deletions when sorting is unnecessary. Performance depends
heavily on a good hash function and low collision rates. Unordered sets are perfect for caching, duplicate
detection, or membership testing in large datasets where order is irrelevant. They represent a key
performance-oriented container in modern C++ for hash-based scenarios.
#include <unordered_set>
#include <iostream>
using namespace std;
int main() {
unordered_set<string> words;
// Insert words
words.insert("apple");
words.insert("banana");
words.insert("cherry");
words.insert("apple"); // Duplicate - won't be added
cout << "Unique words: " << words.size() << endl; // Size: 3
// Fast lookup - O(1) average
if (words.find("banana") != words.end()) {
cout << "Found banana!" << endl;
}
cout << "All words: ";
for (const string& word : words) {
cout << word << " "; // Order may vary
}
// Remove element
words.erase("cherry");
cout << "\nAfter removing cherry: " << words.size() << endl;
return 0;
}
Output:
Found banana!
All words: banana apple cherry
After removing cherry: 2
🔹 Set Operations
Set operations in C++ include union, intersection, difference, and symmetric difference, implemented via
standard algorithms. Functions like std::set_union and std::set_intersection
work on sorted ranges, producing results in output iterators. These operations are foundational for mathematical set
theory and practical tasks like merging lists, finding common elements, or computing exclusive items. While
std::set provides ordered results, algorithms work with any sorted range, offering flexibility.
Mastering these operations enables efficient solutions to many data comparison and combination problems.
Common Set Operations:
- insert(value): Add element to set
- erase(value): Remove element from set
- find(value): Search for element
- count(value): Count occurrences (0 or 1 for set)
- size(): Get number of elements
- empty(): Check if set is empty
- clear(): Remove all elements