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:

Set size: 3
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:

Multiset size: 5
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:

Unique words: 3
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

🧠 Test Your Knowledge

What happens when you insert a duplicate element in a set?