C++ has many valuable elements and tools that help us in competitive programming.

One such component is set present in the Standard Template Library (STL), which provides a way to efficiently store data in a sorted manner.

This guide, “Set in C++ – A Complete Reference,” dives into the detailed concept of using sets in C++, exploring their functionalities, syntax, and applications in programming.

Whether you’re a professional coder looking to enhance your knowledge or a beginner eager to grasp the fundamentals, this reference will serve as your comprehensive companion in mastering sets in C++.

Let’s dive in

**What Is Set In C++?**

In C++, a set is a Standard Template Library (STL) container that stores unique elements in a sorted order. Unlike arrays or vectors, set C++ does not allow duplicate elements, making them ideal for tasks where uniqueness is crucial.

Sets automatically arrange their elements in a specific order, typically ascending, using comparison functions. This ordered arrangement makes sets efficient for searching, insertion, and deletion operations.

Additionally, sets offer a variety of methods for manipulating and accessing their elements, making them a valuable tool in C++ programming, particularly for tasks involving data organization and retrieval.

In C++, sets are part of the Standard Template Library (STL) and are implemented through the std::set class template. Here’s the syntax:

**Syntax**

```
#include <set> // Include the set header
int main() {
// Declaration and initialization of a set
std::set<DataType> set_name;
// Inserting elements into the set
set_name.insert(value);
// Removing elements from the set
set_name.erase(value);
// Iterating through the set
for (auto it = set_name.begin(); it != set_name.end(); ++it) {
// Accessing the current element using *it
}
// Checking if an element exists in the set
if (set_name.find(value) != set_name.end()) {
// Element found
}
// Checking if the set is empty
if (set_name.empty()) {
// Set is empty
}
// Getting the number of elements in the set
int size = set_name.size();
// Clearing all elements from the set
set_name.clear();
return 0;
}
```

**In the above syntax:**

**DataType**is the type of elements that the set will hold.**set_name**is the name of the set.- The
**value**represents the elements you want to insert or remove from the set.

Sets in C++ automatically order their elements based on their values and don’t allow duplicate elements.

**When To Use Sets?**

Sets in C++ are particularly useful in scenarios where:

**Uniqueness Is Essential**

If you must store a collection of elements where each item must be unique, set c++ is the go-to choice. Whether it’s a list of unique identifiers, names, or any other data where duplication isn’t allowed, sets ensure no duplicates are present.

**Maintaining Sorted Order Matters**

C++ sets automatically arrange their elements in sorted order, making them efficient for tasks that require elements to be accessed or retrieved in a specific sequence. This ordered arrangement simplifies searching for elements and ensures that iteration over the set follows a predictable order.

**Efficient Membership Testing**

Sets provide a fast and efficient way to check whether a particular element is present in the collection. This is especially beneficial when dealing with large datasets, as sets offer logarithmic time complexity for insertion, deletion, and search operations.

**Intersection, Union, And Difference Operations**

Sets support various set operations like intersection, union, and difference, which can be immensely helpful in tasks involving comparisons and computations among multiple sets.

**Some of the C++ set examples are shared below for better understanding:**

- Suppose you’re developing a program to manage a database of student records. Using sets in C++, you can ensure that each student’s ID is unique, preventing duplicate entries.

- In a financial application, sets can be employed to maintain a sorted list of transactions. This facilitates efficient searching and retrieval of specific transactions based on criteria such as date or amount.

- When dealing with geometric shapes in a graphics application, sets can help ensure each shape is unique, allowing for easy manipulation and comparison of different shapes.

- Sets in C++ provide a versatile and efficient way to handle collections of unique elements while maintaining a sorted order. Whether working on data manipulation, algorithm design, or any other programming task, understanding when and how to use sets can significantly enhance your efficiency and productivity.

**Set Properties**

**Storing Order**

Sets in C++ store elements in a sorted order. This means the elements are automatically arranged in ascending order based on their values.

**Value Uniqueness**

All elements in a set must have unique values. Duplicate values are not allowed within a set, ensuring that each element is distinct.

**Immutable In Nature**

Once an element is added to a set, its value cannot be modified. While removing an element and adding a modified version of it is possible, the original value remains immutable within the set.

**Search Technique**

Sets in C++ typically utilize a binary search tree implementation for efficient searching. This implementation allows for fast retrieval of elements, especially in large datasets.

**Organizing Sequence**

A set’s values are unindexed, meaning each element has no specific index. Instead, elements are arranged solely based on their values within the set’s sorted order.

**Great Tip To The Great Learners**

If you need to store elements in an unsorted (random) order, you can use the unordered_set() container in C++. This container offers similar functionality to sets but does not maintain a specific order among its elements, providing a different approach to data storage based on hashing.

Join the ranks of elite programmers – Enroll in “Introduction to C++” now!

**How To Create A Set In C++?**

To create a set in C++, you can use the** std::set** class from the Standard Template Library (STL). Sets automatically order their elements and do not allow duplicates.

Here’s a code example demonstrating how to create a set, along with an explanation and the expected output:

```
#include <iostream>
#include <set>
int main() {
// Creating a set of integers
std::set<int> mySet;
// Adding elements to the set
mySet.insert(5);
mySet.insert(3);
mySet.insert(8);
mySet.insert(3); // Duplicate elements are automatically ignored
// Note: We cannot use the [] operator to add elements to a set.
// Doing so will result in an error.
// Printing the elements of the set
std::cout << "Elements of the set: ";
for (int x : mySet) {
std::cout << x << " ";
}
std::cout << std::endl;
// Size of the set
std::cout << "Size of the set: " << mySet.size() << std::endl;
return 0;
}
```

**Output **

```
Elements of the set: 3 5 8
Size of the set: 3
```

**Explanation**

- We include the necessary headers
**<iostream>**and**<set>**to work with sets. - We create a set of integers named mySet using the
**std::set<int>**syntax. - Elements are added to the set using the
**insert()**method. Note that attempting to add duplicate elements (e.g., 3) will not change the set because sets do not allow duplicates. - We iterate through the set using a range-based for loop to print its elements.
- The size of the set is obtained using the
**size()**method and printed to the console.

**Great Tip To The Great Learners**

We cannot use the** [ ]** operator to add elements to a set. Doing so will result in an error.

**How To Sort A Set In Descending Order C++?**

In C++, by default, **std::set** orders its elements in ascending order. If you want to sort set in decreasing order C++, you can use the **std::greate**r comparator with **std::set.** Here’s how you can do it:

```
#include <iostream>
#include <set>
int main() {
// Creating a set of integers with std::greater comparator for descending order
std::set<int, std::greater<int>> mySet;
// Adding elements to the set
mySet.insert(5);
mySet.insert(3);
mySet.insert(8);
mySet.insert(10);
mySet.insert(1);
// Printing the elements of the set (automatically sorted in descending order)
std::cout << "Elements of the set (descending order): ";
for (int x : mySet) {
std::cout << x << " ";
}
std::cout << std::endl;
return 0;
}
```

**Output**

```
Elements of the set (descending order): 10 8 5 3 1
```

**Explanation**

- We include the necessary headers
**<iostream>**and**<set>**to work with sets. - We create a set of integers named
**mySet**using the**std::set<int**,**std::greater<int>>**syntax, where**std::greater<int>**is a comparator that sorts elements in descending order. - Elements are added to the set using the
**insert()**method. - When we iterate through the set, the elements are automatically sorted in descending order due to the comparator specified during the set’s creation.

If you are a beginner, accelerate your learning curve with our beginner’s guide: “C++ Tutorial for Beginners” blog!

**Basic Functions Associated With Set**

**1. Size()**

Returns the number of elements in the set.

**Syntax **

```
size_t size() const;
```

**Example **

```
#include <iostream>
#include <set>
int main() {
// Creating a set of integers
std::set<int> mySet;
// Inserting elements into the set
mySet.insert(10);
mySet.insert(20);
mySet.insert(30);
// Getting the size of the set
size_t setSize = mySet.size();
// Printing the size of the set
std::cout << "Size of the set: " << setSize << std::endl;
return 0;
}
```

**Output **

```
Size of the set: 3
```

**Explanation**

In this example, a set of integers **mySet **is created, and three elements (**10, 20, and 30**) are inserted. The **size()** function is then used to retrieve the number of elements present in the set, which is **3**. Finally, the size of the set is printed to the console.

**2. Empty ()**

Check if the set is empty. Returns true if the set contains no elements; otherwise, it is false.

**Syntax **

```
bool empty() const;
```

**Example **

```
#include <iostream>
#include <set>
int main() {
// Creating a set of integers
std::set<int> mySet;
// Checking if the set is empty
bool isEmpty = mySet.empty();
// Printing whether the set is empty or not
if (isEmpty) {
std::cout << "The set is empty." << std::endl;
} else {
std::cout << "The set is not empty." << std::endl;
}
return 0;
}
```

**Output **

```
The set is empty.
```

**Explanation**

In this example, a set of integers called **mySet **is created. The **empty()** function is then used to check if the set is empty. Since no elements have been inserted into the set, the function returns true, indicating that it is empty.

**3. Insert (val)**

Inserts a new element with the specified value into the set.

**Syntax **

```
std::pair<iterator, bool> insert(const value_type& val);
```

**Example **

```
#include <iostream>
#include <set>
int main() {
// Creating a set of integers
std::set<int> mySet;
// Inserting elements into the set
mySet.insert(10);
mySet.insert(20);
mySet.insert(30);
// Printing the elements of the set
std::cout << "Elements of the set:";
for (auto num : mySet) {
std::cout << " " << num;
}
std::cout << std::endl;
return 0;
}
```

**Output **

```
Elements of the set: 10 20 30
```

**Explanation**

In this example, a set of integers **mySet **is created, and three elements (10, 20, and 30) are inserted into it using the **insert() **function. The elements of the set are then printed to the console, showing that they are stored in sorted order.

**4. Erase (val)**

Removes the element with the specified value from the set if it exists.

**Syntax **

```
size_type erase(const key_type& val);
```

**Example **

```
#include <iostream>
#include <set>
int main() {
// Creating a set of integers
std::set<int> mySet {10, 20, 30, 40};
// Erasing an element from the set
mySet.erase(20);
// Printing the elements of the set
std::cout << "Elements of the set after erasing:";
for (auto num : mySet) {
std::cout << " " << num;
}
std::cout << std::endl;
return 0;
}
```

**Output **

```
Elements of the set after erasing: 10 30 40
```

**Explanation**

This example creates a set of integers **mySet **with elements 10, 20, 30, and 40. The **erase() function** is then used to remove the element with the value 20 from the set. After erasing, the remaining elements of the set are printed to the console, showing that 20 has been successfully removed from the set.

**5. Find (val)**

Searches for the element with the specified value in the set. Returns an iterator to the element if found; otherwise, returns **set::end()**.

**Syntax **

```
iterator find(const key_type& val);
```

**Example **

```
#include <iostream>
#include <set>
int main() {
// Creating a set of integers
std::set<int> mySet {10, 20, 30, 40};
// Finding an element in the set
auto it = mySet.find(20);
// Printing the result
if (it != mySet.end()) {
std::cout << "Element 20 found in the set." << std::endl;
} else {
std::cout << "Element 20 not found in the set." << std::endl;
}
return 0;
}
```

**Output **

```
Element 20 found in the set.
```

**Explanation**

In this example, a set of integers, **mySet**, is created with elements 10, 20, 30, and 40. The** find() **function is then used to search for the element with the value 20 in the set. Since the element is found, the function returns an iterator pointing to it. The result is printed to the console, indicating that element 20 is found in the set.

**6. Clear ()**

Removes all elements from the set, leaving it empty.

**Syntax **

```
void clear();
```

**Example **

```
#include <iostream>
#include <set>
int main() {
// Creating a set of integers
std::set<int> mySet {10, 20, 30, 40};
// Clearing all elements from the set
mySet.clear();
// Printing the size of the set after clearing
std::cout << "Size of the set after clearing: " << mySet.size() << std::endl;
return 0;
}
```

**Output **

```
Size of the set after clearing: 0
```

**Explanation**

In this example, a set of integers, **mySet**, is created with elements 10, 20, 30, and 40. The **clear()** function removes all elements from the set, leaving it empty. After clearing, the size of the set is printed to the console, which shows that it is empty.

**7. begin() and end()**

Return iterators pointing to the first and past-the-end elements of the set, respectively. These iterators can be used to traverse the set.

**Syntax **

```
iterator begin();
iterator end();
```

**Example **

```
#include <iostream>
#include <set>
int main() {
// Creating a set of integers
std::set<int> mySet {10, 20, 30, 40};
// Using iterators to print elements of the set
std::cout << "Elements of the set:";
for (auto it = mySet.begin(); it != mySet.end(); ++it) {
std::cout << " " << *it;
}
std::cout << std::endl;
return 0;
}
```

**Output **

```
Elements of the set: 10 20 30 40
```

**Explanation**

In this example, a set of integers, **mySet**, is created with elements 10, 20, 30, and 40. The **begin()** function returns an iterator pointing to the first element of the set, while the **end() **function returns an iterator pointing to the position just after the last element. Using these iterators, a loop is employed to iterate over the set’s elements and print them to the console.

**8. lower_bound(val) and upper_bound(val)**

Return iterators to the first element not less than (lower_bound) or greater than (upper_bound) a given value.

**Syntax **

```
iterator lower_bound(const key_type& val);
iterator upper_bound(const key_type& val);
```

**Example **

```
#include <iostream>
#include <set>
int main() {
// Creating a set of integers
std::set<int> mySet {10, 20, 30, 40};
// Using lower_bound and upper_bound
auto lower = mySet.lower_bound(20);
auto upper = mySet.upper_bound(30);
// Printing the range between lower_bound and upper_bound
std::cout << "Elements in range [lower_bound, upper_bound):";
for (auto it = lower; it != upper; ++it) {
std::cout << " " << *it;
}
std::cout << std::endl;
return 0;
}
```

**Output **

```
Elements in range [lower_bound, upper_bound): 20 30
```

**Explanation**

This example creates a set of integers **mySet **with elements 10, 20, 30, and 40. The **lower_bound(20)** function returns an iterator to the first element not less than 20, while the **upper_bound(30) **function returns an iterator to the first element greater than 30.

Using these iterators, a loop is employed to iterate over the elements between lower_bound and upper_bound (excluding upper_bound) and print them to the console.

These c++ set functions provide essential functionality for adding, removing, searching, and managing elements within a set in C++.

Also, Learn everything you need to know about C++ Functions

**Some Other Functions Of Set In C++ **

Function | Description |

count(val) | Counts the number of elements with the specified value in the set. |

Emplace (args) | Constructs elements in place in the set, avoiding unnecessary copies. |

emplace_hint() | Constructs elements in place in the set with a hint for the position, optimizing insertion efficiency. |

equal_range(val) | Returns a range containing all elements with the given value in the set. |

max_size() | Returns the maximum possible number of elements the set can hold. |

operator==() | Checks if two sets are equal, i.e., contain the same elements. |

Operator!=() | Checks if two sets are not equal, i.e., contain different elements. |

Swap () | Swaps the contents of two sets efficiently. |

get_allocator() | Returns the allocator associated with the set, which can be used for memory management. |

key_comp() | Returns the comparison function used to order the elements in the set by their keys. |

value_comp() | Returns the comparison function used to order the elements in the set by their values. |

rbegin() | Returns a reverse iterator pointing to the last element in the set. |

rend() | Returns a reverse iterator pointing to the position just before the first element in the set. |

Extract () | Extracts an element from the set using a given iterator, returning a handle to it for further manipulation or insertion into another container. |

Merge () | Merges elements from another set into the current set, maintaining sorted order and ensuring the uniqueness of elements. |

**Difference Between Set, Multiset, and Unordered_set**

Parameters | set | multiset | unordered_set |

Storage Order | Stores elements in a sorted manner | Stores elements in a sorted manner – in increasing or decreasing order | Stores elements in an unsorted order |

Type of elements | Holds unique elements only | It can hold duplicate values | Only unique values are allowed |

Modification | Insertion and deletion of elements are possible, but modification of elements is not allowed | Deletion of elements can be done with the help of iterators | Insertion and deletion of elements are possible, but modification of elements is not allowed |

Implementation | Implemented internally via Binary Search Trees | Internal implementation through Binary Search Trees | Implemented internally using Hash Tables |

Erasing element | More than one elements can be erased by giving the starting and ending iterator | We can erase that element for which the iterator position is given | We can erase that element for which the iterator position is given |

Syntax | set<datatype> setName | multiset<datatype> multiSetName; | unordered_set<datatype> UnorderedSetName; |

Build a stellar portfolio with these handpicked “C++ Projects To Work On In 2024“

**Wrapping UP**

In conclusion, “Set in C++ – A Complete Reference” offers a comprehensive guide to mastering sets in C++, providing essential knowledge for efficient data organization and manipulation.

Whether you’re a beginner learning the basics or an experienced programmer seeking advanced techniques, this reference equips you with the skills to effectively leverage sets in your C++ projects.

Additionally, if you’re looking to expand your programming skills further, Great Learning offers two distinct courses: a Free C++ Tutorial Course and a Software Development Course.

The Free C++ Tutorial Course is an ideal starting point for learning C++ from scratch, covering fundamental concepts with practical examples.

On the other hand, the Software Development Course delves deeper into software engineering principles, equipping you with the expertise needed to excel in real-world software development projects.

Whether aiming to enhance your programming proficiency or embark on a career in software development, Great Learning provides tailored courses to suit your learning goals.

**FAQs **

**How do sets differ from vectors and arrays in C++?**Sets differ from vectors and arrays in several ways:

1. Sets store unique elements in sorted order, while vectors and arrays can contain duplicate elements and do not maintain a specific order.

2. Sets have efficient search, insertion, and deletion operations (O(log n)), whereas vectors and arrays have linear search (O(n)) and insertion/deletion (O(n)) complexities.

3. Sets automatically sort their elements, while vectors and arrays require manual sorting if ordered data is needed.

**Q: Can custom data types be used with sets in C++, and if so, how do you define the comparison function for sorting?**Yes, custom data types can be used with sets in C++. You must define a comparison function or overload the less-than operator **(<)** for the custom data type to do so.

This comparison function should return true if the first argument is less than the second argument and false otherwise, ensuring the proper ordering of elements within the set.

**Q: How does the performance of sets in C++ degrade with large datasets, and are there any optimization techniques to mitigate this degradation?**As the dataset size increases, the performance of sets in C++ may degrade due to the logarithmic time complexity of operations such as insertion, deletion, and search.

To mitigate this degradation, techniques such as using the unordered_set container (if order is not essential), employing custom allocators to reduce memory fragmentation, or optimizing the comparison function for custom data types can be beneficial.

**Q: How do sets in C++ handle memory allocation and deallocation, especially in scenarios involving frequent insertion and deletion of elements?**Sets in C++ manage memory allocation and deallocation internally, typically using dynamic memory allocation for node-based structures in the case of ordered sets.

Frequent insertion and deletion of elements may lead to memory fragmentation over time, potentially impacting performance.

To mitigate this, techniques such as custom memory allocators or periodically reorganizing the set structure (e.g., using std::set::rebalance) can help maintain optimal memory usage.

**Q: What is the time complexity of operations on a set in C++?**Operations such as insertion, deletion, and search in a set have a time complexity of O(log n), where n is the number of elements in the set. This is because sets are typically implemented using balanced binary search trees like Red-Black Trees.