std::set
std::set
is a container in the C++ Standard Template Library (STL) that stores unique elements in a sorted order. It is implemented as a balanced binary search tree, typically a red-black tree, which ensures logarithmic time complexity for insertion, deletion, and search operations.
#include <iostream>
#include <set>
#include <string>
int main() {
std::set<int> numbers = {5, 2, 8, 1, 9, 3, 7};
// Inserting elements
numbers.insert(4);
numbers.insert(6);
numbers.insert(2); // Duplicate, won't be inserted
// Printing the set
std::cout << "Numbers in the set:" << std::endl;
for (const auto& num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// Checking if an element exists
if (numbers.find(5) != numbers.end()) {
std::cout << "5 is in the set" << std::endl;
}
// Removing an element
numbers.erase(3);
// Size of the set
std::cout << "Number of elements: " << numbers.size() << std::endl;
return 0;
}
set
of integers is created and initializedinsert()
is used to add new elementsfind()
is used to check for the existence of an elementerase()
removes an element from the setsize()
returns the number of elements in the set#include <iostream>
#include <set>
#include <string>
struct Person {
std::string name;
int age;
bool operator<(const Person& other) const {
return age < other.age;
}
};
// Custom comparator for descending order
struct PersonComparator {
bool operator()(const Person& a, const Person& b) const {
return a.age > b.age;
}
};
int main() {
std::set<Person, PersonComparator> people;
people.insert({"Alice", 30});
people.insert({"Bob", 25});
people.insert({"Charlie", 35});
people.insert({"David", 28});
for (const auto& person : people) {
std::cout << person.name << ": " << person.age << std::endl;
}
return 0;
}
Person
struct is defined with a <
operator for default sortingPersonComparator
is created for descending age orderset
is initialized with Person
objects and the custom comparatorstd::set
#include <iostream>
#include <set>
#include <algorithm>
void printSet(const std::set<int>& s, const std::string& name) {
std::cout << name << ": ";
for (int num : s) {
std::cout << num << " ";
}
std::cout << std::endl;
}
int main() {
std::set<int> set1 = {1, 2, 3, 4, 5};
std::set<int> set2 = {4, 5, 6, 7, 8};
printSet(set1, "Set 1");
printSet(set2, "Set 2");
// Union
std::set<int> unionSet;
std::set_union(set1.begin(), set1.end(), set2.begin(), set2.end(),
std::inserter(unionSet, unionSet.begin()));
printSet(unionSet, "Union");
// Intersection
std::set<int> intersectionSet;
std::set_intersection(set1.begin(), set1.end(), set2.begin(), set2.end(),
std::inserter(intersectionSet, intersectionSet.begin()));
printSet(intersectionSet, "Intersection");
// Difference (set1 - set2)
std::set<int> differenceSet;
std::set_difference(set1.begin(), set1.end(), set2.begin(), set2.end(),
std::inserter(differenceSet, differenceSet.begin()));
printSet(differenceSet, "Difference (set1 - set2)");
// Symmetric Difference
std::set<int> symDifferenceSet;
std::set_symmetric_difference(set1.begin(), set1.end(), set2.begin(), set2.end(),
std::inserter(symDifferenceSet, symDifferenceSet.begin()));
printSet(symDifferenceSet, "Symmetric Difference");
return 0;
}
std::set
and algorithms from <algorithm>
set_union
computes the union of two setsset_intersection
finds the common elements between two setsset_difference
computes the elements in set1
that are not in set2
set_symmetric_difference
finds elements in either set but not in bothstd::inserter
is used to insert elements into the result setsstd::unordered_set
#include <iostream>
#include <set>
#include <unordered_set>
#include <chrono>
#include <random>
template<typename Func>
long long measureTime(Func func) {
auto start = std::chrono::high_resolution_clock::now();
func();
auto end = std::chrono::high_resolution_clock::now();
return std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
}
int main() {
const int NUM_ELEMENTS = 1000000;
const int NUM_SEARCHES = 10000;
std::set<int> orderedSet;
std::unordered_set<int> unorderedSet;
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, NUM_ELEMENTS);
// Insertion
auto insertOrdered = [&]() {
for (int i = 0; i < NUM_ELEMENTS; ++i) {
orderedSet.insert(dis(gen));
}
};
auto insertUnordered = [&]() {
for (int i = 0; i < NUM_ELEMENTS; ++i) {
unorderedSet.insert(dis(gen));
}
};
std::cout << "Insertion time (microseconds):" << std::endl;
std::cout << "set: " << measureTime(insertOrdered) << std::endl;
std::cout << "unordered_set: " << measureTime(insertUnordered) << std::endl;
// Search
auto searchOrdered = [&]() {
for (int i = 0; i < NUM_SEARCHES; ++i) {
orderedSet.find(dis(gen));
}
};
auto searchUnordered = [&]() {
for (int i = 0; i < NUM_SEARCHES; ++i) {
unorderedSet.find(dis(gen));
}
};
std::cout << "Search time (microseconds):" << std::endl;
std::cout << "set: " << measureTime(searchOrdered) << std::endl;
std::cout << "unordered_set: " << measureTime(searchUnordered) << std::endl;
return 0;
}
std::set
and std::unordered_set
measureTime
function calculates execution timestd::set
typically shows slower insertion and search times due to its ordered naturestd::set
maintains elements in sorted order, which can be beneficial in certain scenariosIterator Stability: Iterators and references to elements in a set
remain valid after insertion or deletion of other elements.
Memory Overhead: set
typically has higher memory overhead compared to unordered_set
due to the balanced tree structure.
Ordered Operations: set
provides efficient operations for finding the next or previous element, which is not possible with unordered_set
.
No Direct Element Modification: Elements in a set
cannot be modified directly through iterators to maintain the correct ordering.
std::set
is a versatile container in C++ for storing unique elements in a sorted order. Key points to remember:
unordered_set
for basic operations, it maintains order and supports efficient range queriesstd::set
is particularly useful in situations where you need to maintain a sorted collection of unique elements, perform range-based queries, or when the order of elements is important. It's commonly used in implementing algorithms that require ordered data, maintaining sorted lists of items, and in scenarios where both uniqueness and order are crucial.