|
1 | 1 | ---
|
2 | 2 | Title: 'Sets'
|
3 |
| -Description: 'Sets are associative containers that store unique elements which can be referenced by the value of the element.' |
| 3 | +Description: 'Stores unique elements in sorted order with efficient insertion, deletion, and search operations.' |
4 | 4 | Subjects:
|
5 | 5 | - 'Computer Science'
|
6 | 6 | - 'Game Development'
|
7 | 7 | Tags:
|
8 |
| - - 'Data Types' |
9 |
| - - 'Sets' |
| 8 | + - 'Algorithms' |
| 9 | + - 'Containers' |
| 10 | + - 'Data Structures' |
| 11 | + - 'STL' |
10 | 12 | CatalogContent:
|
11 | 13 | - 'learn-c-plus-plus'
|
12 | 14 | - 'paths/computer-science'
|
13 | 15 | ---
|
14 | 16 |
|
15 |
| -**Sets** are associative containers which store unique elements that can be referenced by an element's value. The value, which is itself the key to access an element in the set, is constant. Once assigned it cannot be changed. However, existing values can be removed or new values can be added. |
| 17 | +A **set** is an associative container in the C++ Standard Template Library that stores unique elements in a sorted order. Sets automatically maintain their elements in ascending order by default, though this can be customized using a comparison function. Sets provide efficient insertion, deletion, and search operations with logarithmic time complexity. |
16 | 18 |
|
17 |
| -## Syntax |
| 19 | +Sets are commonly used in scenarios where you need to maintain a collection of unique elements with fast lookup capabilities, such as removing duplicates from data, implementing mathematical set operations, maintaining sorted collections, and checking membership efficiently. They are particularly useful in algorithms that require frequent searching and when the order of elements matters. |
| 20 | + |
| 21 | +## Creating a Set |
| 22 | + |
| 23 | +The basic syntax for creating a set is: |
| 24 | + |
| 25 | +```pseudo |
| 26 | +set<dataType> setName; |
| 27 | +``` |
| 28 | + |
| 29 | +**Parameters:** |
| 30 | + |
| 31 | +- `dataType`: The type of elements to be stored in the set (e.g., int, string, char) |
| 32 | +- `setName`: The name assigned to the set variable |
| 33 | + |
| 34 | +Sets can also be created with custom comparison functions: |
18 | 35 |
|
19 | 36 | ```pseudo
|
20 |
| -std::set<dataType> setName; |
| 37 | +set<dataType, comparatorFunction> setName; |
21 | 38 | ```
|
22 | 39 |
|
23 |
| -A set can be created by using the `set` keyword and declaring a [data type](https://www.codecademy.com/resources/docs/cpp/data-types) and name. |
| 40 | +Additional parameters: |
| 41 | + |
| 42 | +- `comparatorFunction`: Optional parameter that defines custom sorting order for elements |
24 | 43 |
|
25 |
| -## Example |
| 44 | +## Example: Basic Set Creation |
26 | 45 |
|
27 |
| -The example below initiates a set, inserts values into it using the [.insert()](https://www.codecademy.com/resources/docs/cpp/sets/insert) method, and then prints out the set: |
| 46 | +This example demonstrates different ways to create and initialize a set: |
28 | 47 |
|
29 | 48 | ```cpp
|
30 | 49 | #include <iostream>
|
31 | 50 | #include <set>
|
| 51 | +using namespace std; |
32 | 52 |
|
33 | 53 | int main() {
|
34 |
| - // Initiate set |
35 |
| - std::set<int> numSet; |
36 |
| - |
37 |
| - // Insert values into set |
38 |
| - numSet.insert(25); |
39 |
| - numSet.insert(42); |
40 |
| - numSet.insert(10); |
41 |
| - numSet.insert(19); |
42 |
| - |
43 |
| - // Print out set |
44 |
| - std::set<int> :: iterator iter; |
45 |
| - for (iter = numSet.begin(); iter != numSet.end(); iter++) { |
46 |
| - std::cout<< *iter << " "; |
| 54 | + // Creating an empty set |
| 55 | + set<int> emptySet; |
| 56 | + |
| 57 | + // Creating a set with initializer list |
| 58 | + set<int> numbers = {10, 5, 20, 15, 5, 10}; |
| 59 | + |
| 60 | + // Display the set elements |
| 61 | + cout << "Set contains: "; |
| 62 | + for (int num : numbers) { |
| 63 | + cout << num << " "; |
47 | 64 | }
|
| 65 | + cout << endl; |
| 66 | + |
| 67 | + return 0; |
48 | 68 | }
|
49 | 69 | ```
|
50 | 70 |
|
51 |
| -This outputs the following: |
| 71 | +The output of this code is: |
52 | 72 |
|
53 | 73 | ```shell
|
54 |
| -10 19 25 42 |
| 74 | +Set contains: 5 10 15 20 |
55 | 75 | ```
|
56 | 76 |
|
57 |
| -By default, values of the set are sorted in ascending order. |
| 77 | +The set automatically removes duplicate values (5 and 10 appeared twice) and maintains elements in sorted order. |
| 78 | + |
| 79 | +## Inserting Elements |
| 80 | + |
| 81 | +Elements can be added to a set using the [`insert()`](https://www.codecademy.com/resources/docs/cpp/sets/insert) method. The `insert()` function automatically places elements in their correct sorted position: |
58 | 82 |
|
59 |
| -## Setting a Different Comparison Function |
| 83 | +```cpp |
| 84 | +#include <iostream> |
| 85 | +#include <set> |
| 86 | +using namespace std; |
60 | 87 |
|
61 |
| -The comparison function can be changed from the default to `std::greater<dataType>` in order to sort the values in descending order. |
| 88 | +int main() { |
| 89 | + set<int> numbers; |
62 | 90 |
|
63 |
| -### Syntax |
| 91 | + // Insert individual elements |
| 92 | + numbers.insert(25); |
| 93 | + numbers.insert(10); |
| 94 | + numbers.insert(30); |
| 95 | + numbers.insert(10); // Duplicate - will not be added |
64 | 96 |
|
65 |
| -```pseudo |
66 |
| -std::set<dataType, std::greater<dataType> > setName; |
| 97 | + cout << "Set after insertions: "; |
| 98 | + for (int num : numbers) { |
| 99 | + cout << num << " "; |
| 100 | + } |
| 101 | + cout << endl; |
| 102 | + |
| 103 | + return 0; |
| 104 | +} |
| 105 | +``` |
| 106 | + |
| 107 | +Output of this code is: |
| 108 | + |
| 109 | +```shell |
| 110 | +Set after insertions: 10 25 30 |
| 111 | +``` |
| 112 | + |
| 113 | +The duplicate value 10 was automatically ignored, and elements are displayed in sorted order regardless of insertion order. |
| 114 | + |
| 115 | +## Accessing Elements |
| 116 | + |
| 117 | +Unlike arrays or vectors, sets do not support direct index-based access. Elements are accessed using iterators or by checking for existence using the [`find()`](https://www.codecademy.com/resources/docs/cpp/sets/find) method: |
| 118 | + |
| 119 | +```cpp |
| 120 | +#include <iostream> |
| 121 | +#include <set> |
| 122 | +using namespace std; |
| 123 | + |
| 124 | +int main() { |
| 125 | + set<int> numbers = {15, 25, 35, 45, 55}; |
| 126 | + |
| 127 | + // Access first element using iterator |
| 128 | + auto firstElement = numbers.begin(); |
| 129 | + cout << "First element: " << *firstElement << endl; |
| 130 | + |
| 131 | + // Check if element exists using find() |
| 132 | + auto searchResult = numbers.find(35); |
| 133 | + if (searchResult != numbers.end()) { |
| 134 | + cout << "Element 35 found: " << *searchResult << endl; |
| 135 | + } else { |
| 136 | + cout << "Element 35 not found" << endl; |
| 137 | + } |
| 138 | + |
| 139 | + return 0; |
| 140 | +} |
| 141 | +``` |
| 142 | + |
| 143 | +The output of the code is: |
| 144 | + |
| 145 | +```shell |
| 146 | +First element: 15 |
| 147 | +Element 35 found: 35 |
67 | 148 | ```
|
68 | 149 |
|
69 |
| -The `dataType` for the comparison function must match the data type of the `set`. |
| 150 | +The `find()` method returns an iterator pointing to the element if found, or `end()` iterator if the element doesn't exist. |
70 | 151 |
|
71 |
| -### Codebyte Example |
| 152 | +## Updating Elements |
72 | 153 |
|
73 |
| -Setting the previous example's comparison function to `std::greater<int>`: |
| 154 | +Sets do not allow modification of existing elements because changing an element's value could disrupt the sorted order. To update an element, you must remove the old value and insert the new one: |
74 | 155 |
|
75 |
| -```codebyte/cpp |
| 156 | +```cpp |
76 | 157 | #include <iostream>
|
77 | 158 | #include <set>
|
| 159 | +using namespace std; |
78 | 160 |
|
79 | 161 | int main() {
|
80 |
| - // Initiate set |
81 |
| - std::set<int, std::greater<int> > numSet; |
| 162 | + set<int> numbers = {10, 20, 30, 40}; |
82 | 163 |
|
83 |
| - // Insert values into set |
84 |
| - numSet.insert(25); |
85 |
| - numSet.insert(42); |
86 |
| - numSet.insert(10); |
87 |
| - numSet.insert(19); |
| 164 | + cout << "Original set: "; |
| 165 | + for (int num : numbers) { |
| 166 | + cout << num << " "; |
| 167 | + } |
| 168 | + cout << endl; |
88 | 169 |
|
89 |
| - // Print set |
90 |
| - std::set<int> :: iterator iter; |
| 170 | + // To "update" 30 to 35, remove 30 and insert 35 |
| 171 | + numbers.erase(30); |
| 172 | + numbers.insert(35); |
91 | 173 |
|
92 |
| - for (iter = numSet.begin(); iter != numSet.end(); iter++) { |
93 |
| - std::cout<< *iter << " "; |
| 174 | + cout << "Updated set: "; |
| 175 | + for (int num : numbers) { |
| 176 | + cout << num << " "; |
94 | 177 | }
|
| 178 | + cout << endl; |
| 179 | + |
| 180 | + return 0; |
95 | 181 | }
|
96 | 182 | ```
|
| 183 | + |
| 184 | +The output of the code is: |
| 185 | + |
| 186 | +```shell |
| 187 | +Original set: 10 20 30 40 |
| 188 | +Updated set: 10 20 35 40 |
| 189 | +``` |
| 190 | + |
| 191 | +The element 30 was removed and 35 was inserted, maintaining the sorted order of the set. |
| 192 | + |
| 193 | +## Deleting Elements |
| 194 | + |
| 195 | +Elements can be removed from a set using the [`erase()`](https://www.codecademy.com/resources/docs/cpp/sets/erase) method, which can remove elements by value or by iterator position: |
| 196 | + |
| 197 | +```cpp |
| 198 | +#include <iostream> |
| 199 | +#include <set> |
| 200 | +using namespace std; |
| 201 | + |
| 202 | +int main() { |
| 203 | + set<int> numbers = {100, 200, 300, 400, 500}; |
| 204 | + |
| 205 | + cout << "Original set: "; |
| 206 | + for (int num : numbers) { |
| 207 | + cout << num << " "; |
| 208 | + } |
| 209 | + cout << endl; |
| 210 | + |
| 211 | + // Remove element by value |
| 212 | + numbers.erase(300); |
| 213 | + |
| 214 | + // Remove element by iterator (first element) |
| 215 | + numbers.erase(numbers.begin()); |
| 216 | + |
| 217 | + cout << "Set after deletions: "; |
| 218 | + for (int num : numbers) { |
| 219 | + cout << num << " "; |
| 220 | + } |
| 221 | + cout << endl; |
| 222 | + |
| 223 | + return 0; |
| 224 | +} |
| 225 | +``` |
| 226 | + |
| 227 | +The output of the code is: |
| 228 | + |
| 229 | +```shell |
| 230 | +Original set: 100 200 300 400 500 |
| 231 | +Set after deletions: 200 400 500 |
| 232 | +``` |
| 233 | + |
| 234 | +The value 300 was removed directly, and the first element (100) was removed using an iterator. |
| 235 | + |
| 236 | +## Codebyte Example: Student Grade Tracker |
| 237 | + |
| 238 | +This comprehensive example demonstrates a practical application using sets to track unique student grades and perform various operations: |
| 239 | + |
| 240 | +```cpp |
| 241 | +#include <iostream> |
| 242 | +#include <set> |
| 243 | +#include <string> |
| 244 | +using namespace std; |
| 245 | + |
| 246 | +int main() { |
| 247 | + set<int> uniqueGrades; |
| 248 | + |
| 249 | + // Adding grades from different students |
| 250 | + int grades[] = {85, 92, 78, 85, 96, 78, 88, 92, 75, 96}; |
| 251 | + int numGrades = sizeof(grades) / sizeof(grades[0]); |
| 252 | + |
| 253 | + cout << "Adding grades: "; |
| 254 | + for (int i = 0; i < numGrades; i++) { |
| 255 | + cout << grades[i] << " "; |
| 256 | + uniqueGrades.insert(grades[i]); |
| 257 | + } |
| 258 | + cout << endl; |
| 259 | + |
| 260 | + // Display unique grades in sorted order |
| 261 | + cout << "Unique grades (sorted): "; |
| 262 | + for (int grade : uniqueGrades) { |
| 263 | + cout << grade << " "; |
| 264 | + } |
| 265 | + cout << endl; |
| 266 | + |
| 267 | + // Find highest and lowest grades |
| 268 | + cout << "Lowest grade: " << *uniqueGrades.begin() << endl; |
| 269 | + cout << "Highest grade: " << *uniqueGrades.rbegin() << endl; |
| 270 | + |
| 271 | + // Check if a specific grade exists |
| 272 | + int searchGrade = 90; |
| 273 | + if (uniqueGrades.find(searchGrade) != uniqueGrades.end()) { |
| 274 | + cout << "Grade " << searchGrade << " exists" << endl; |
| 275 | + } else { |
| 276 | + cout << "Grade " << searchGrade << " does not exist" << endl; |
| 277 | + } |
| 278 | + |
| 279 | + // Remove failing grades (below 80) |
| 280 | + auto it = uniqueGrades.begin(); |
| 281 | + while (it != uniqueGrades.end()) { |
| 282 | + if (*it < 80) { |
| 283 | + it = uniqueGrades.erase(it); |
| 284 | + } else { |
| 285 | + ++it; |
| 286 | + } |
| 287 | + } |
| 288 | + |
| 289 | + cout << "Passing grades only: "; |
| 290 | + for (int grade : uniqueGrades) { |
| 291 | + cout << grade << " "; |
| 292 | + } |
| 293 | + cout << endl; |
| 294 | + |
| 295 | + cout << "Total unique passing grades: " << uniqueGrades.size() << endl; |
| 296 | + |
| 297 | + return 0; |
| 298 | +} |
| 299 | +``` |
| 300 | + |
| 301 | +This example shows how sets automatically handle duplicates, maintain sorted order, and provide efficient operations for real-world data processing scenarios. |
| 302 | + |
| 303 | +## Frequently Asked Questions |
| 304 | + |
| 305 | +### 1. Can sets contain duplicate elements? |
| 306 | + |
| 307 | +No, sets automatically prevent duplicate elements. If you try to insert a duplicate value, the insertion is ignored and the set remains unchanged. |
| 308 | + |
| 309 | +### 2. How are elements ordered in a set? |
| 310 | + |
| 311 | +By default, elements are stored in ascending order using the less-than operator. You can provide a custom comparison function to change the sorting behavior. |
| 312 | + |
| 313 | +### 3. What is the time complexity of set operations? |
| 314 | + |
| 315 | +Most set operations (insert, delete, find) have `O(log n)` time complexity due to the underlying balanced binary search tree implementation. |
| 316 | + |
| 317 | +### 4. Can I store custom objects in a set? |
| 318 | + |
| 319 | +Yes, but you must either define the less-than operator for your custom class or provide a custom comparison function when declaring the set. |
| 320 | + |
| 321 | +### 5. How do I iterate through a set in reverse order? |
| 322 | + |
| 323 | +Use reverse iterators with `rbegin()` and `rend()`, or iterate from `rbegin()` to `rend()` using a reverse iterator loop. |
0 commit comments