└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # C++ STL Quick Help 2 | It contains C++ STLs usage and quick help with easy to understand comments and examples (copy+paste to use). 3 | I learned these while solving different kinds of Leetcode Questions. 4 | I will be using "int, string etc" for ease and not complex entities like pairs, structs etc šŸ˜‰. You can replace it with any data structure 5 | If you are confused with the syntax or description, see the example. I am sure that will clear things BECAUSE I have specifically chosen 6 | :mag_right: "EASY + IMPORTANT + MOST USED" examples. 7 | Last but not least, I have added Leetcode Qns also which can be easily solved using STLs 8 | 9 | ### :memo:Different ways of using priority_queue (i.e. heap) :mount_fuji: 10 | 11 | - Default declarations 12 | ```c++ 13 | priority_queue pq; //creates max-heap 14 | priority_queue> pq; //creates max-heap 15 | ``` 16 |
17 | 18 | - writing comparator function for priority_queue 19 | ```c++ 20 | 1. Using in-built comparator provided by C++ : 21 | 22 | priority_queue, greater> pq; //creates min-heap 23 | priority_queue< pair, vector>, greater> > pq; //min_heap of pairs 24 | priority_queue< pair, vector>, greater<> > pq; //min_heap of pairs 25 | ``` 26 | ```c++ 27 | 2. Using user defined comparator as a structure 28 | 29 | struct comp { 30 | bool operator()(int &a, int &b) { 31 | return ab; //min-heap 33 | } 34 | }; 35 | 36 | priority_queue, comp> pq; //usage 37 | ``` 38 | 39 | ```c++ 40 | 3. Using user defined comparator as a function 41 | 42 | static bool comp(int &a, int &b) { 43 | return ab; //min-heap 45 | } 46 | 47 | priority_queue, function > pq(comp); //usage 48 | ``` 49 | ```c++ 50 | 4. Using lambda function 51 | 52 | auto comp = [](int &a, int &b) { 53 | return ab; //min-heap 55 | }; 56 | 57 | priority_queue, decltype(comp) > pq(comp); //usage 58 | 59 | NOTE : 60 | You can receive parameters inside [] as well i.e. auto comp = [some_parameters] 61 | Ex : You want to access a map inside this lambda function 62 | unordered_map mp; 63 | 64 | auto comp = [&mp](int &a, int &b) { 65 | return mp[a] < mp[b]; //etc. 66 | }; 67 | 68 | ``` 69 | 70 | ### :memo: When and why to use std::move() :arrow_left: 71 | ```c++ 72 | /* 73 | To efficiently transfer the resources from source to target. 74 | By efficient, I mean no usage of extra space and time for creating copy. 75 | */ 76 | Examples : 77 | string source = "MIK"; 78 | string target = ""; 79 | target = std::move(source); 80 | cout << " source = " << source << endl; 81 | cout << "target = " << target << endl; 82 | /* 83 | output : 84 | source = 85 | target = "MIK" 86 | */ 87 | 88 | vector v; 89 | string str = "example"; 90 | v.push_back(std::move(str)); 91 | /* 92 | After this, str becomes empty i.e. "" 93 | And while moving str inside v, no extra copy of str was done implicitly. 94 | */ 95 | 96 | vector temp{1, 2, 3}; 97 | vector> result; 98 | result.push_back(std::move(temp)); 99 | /* 100 | This allows no copy of "temp" being created. 101 | It ensures that the contents of "temp" 102 | will be moved into the "result". This is less 103 | expensive, also means temp will now be empty. 104 | */ 105 | ``` 106 | 107 | ### :memo: std::accumulate(begin_iterator, end_iterator, initial_sum) :heavy_plus_sign: 108 | ```c++ 109 | int sum = 0; 110 | vector nums{1, 3, 2, 5}; 111 | sum = accumulate(begin(nums), end(nums), 0); 112 | 113 | cout << sum; //11 114 | 115 | Benefit : You didn't have to write for loop to find the sum 116 | ``` 117 | 118 | ### :memo: std::accumulate(begin_iterator, end_iterator, initial_sum, lambda) :heavy_plus_sign: 119 | ```c++ 120 | lambda : Binary operation taking an element of type as first argument and an 121 | element in the range as second, and which returns a value that can be assigned to type T. 122 | 123 | Example-1 : 124 | 125 | auto lambda = [&](int s, long n) { 126 | return s + n*n; //sums the square of numbers 127 | //You can call any other function inside as well 128 | }; 129 | 130 | int sum = 0; 131 | vector nums{1, 3, 2, 5}; 132 | sum = accumulate(begin(nums), end(nums), 0, lambda); 133 | 134 | cout << sum; //39 135 | 136 | Example-2 : Handling 2-D matrix 137 | //Summming all elements row by row 138 | auto lambda = [&](int sum, vector vec) { 139 | sum = sum + accumulate(begin(vec), end(vec), 0); 140 | return sum; 141 | }; 142 | 143 | int result = accumulate(matrix.begin(), matrix.end(), 0, lambda); 144 | 145 | 146 | Beautiful example and usage : 147 | Leetcode-1577 (My Approach - https://leetcode.com/problems/number-of-ways-where-square-of-number-is-equal-to-product-of-two-numbers/discuss/1305961/C%2B-(A-very-simple-Two-Sum-like-approach) 148 | 149 | Leetcode-1572 (My Approach - https://leetcode.com/problems/matrix-diagonal-sum/discuss/3498479/Using-C%2B%2B-STL-%3A-accumulate) 150 | 151 | ``` 152 | 153 | ### :memo: min_element(begin_iterator, end_iterator), max_element(begin_iterator, end_iterator), minmax_element(begin_iterator, end_iterator) :astonished: 154 | ```c++ 155 | vector nums{1, 3, 2, 5}; 156 | 157 | int minimumValue = *min_element(begin(nums), end(nums)); //1 158 | int maximumValue = *max_element(begin(nums), end(nums)); //5 159 | OR, 160 | auto itr = minmax_element(begin(nums), end(nums)); 161 | int minimumValue = *itr.first; //remember, first is minimum //1 162 | int maximumValue = *itr.second; //remember, second is maximum //5 163 | 164 | 165 | Benefit : You didn't have to write for loop to find the max or min element 166 | ``` 167 | 168 | ### :memo: upper_bound(), lower_bound() in sorted vector, ordered set, ordered map :outbox_tray: 169 | ```c++ 170 | 171 | For vector: 172 | vector vec{10,20,30,30,20,10,10,20}; 173 | vector::iterator up = upper_bound(begin(vec), end(vec), 35);//returns iterator to first element "greater" than 35 174 | vector::iterator low = lower_bound(begin(vec), end(vec), 35);//returns iterator to first element "greater or equal" to 35 175 | cout << "upper_bound at position " << (up - vec.begin()) << '\n'; 176 | cout << "lower_bound at position " << (low- vec.begin()) << '\n'; 177 | 178 | For set: 179 | st.upper_bound(35); //returns iterator to first element "greater" than 35 180 | st.lower_bound(35); //returns iterator to first element "greater or equal" than 35 181 | 182 | For map: 183 | mp.upper_bound(35); //returns iterator to first element "greater" than 35 184 | mp.lower_bound(35); //returns iterator to first element "greater or equal" than 35 185 | 186 | Benefit : You didn't have to write binary search (in case of vector), 187 | JAVA's tree_map equivalent in C++ (in case of map or set) 188 | There are amazing applications or problems that can be solved using the above concepts. 189 | Example : My Calendar I (Leetcode - 729) - 190 | You can find it in my interview_ds_algo repository as well B-) 191 | ``` 192 | 193 | ### :memo: std::rotate šŸŒ€ 194 | ```c++ 195 | vector vec{1, 2, 3, 4}; 196 | int n = vec.size(); 197 | int k = 2; 198 | 199 | rotate(vec.begin(), vec.begin()+k, vec.end()); //Left Rotate by K times 200 | 201 | rotate(vec.begin(), vec.begin()+n-k, vec.end()); //Right Rotate by K times 202 | 203 | ``` 204 | 205 | ### :memo: To check if some rotation of string s can become string tšŸŒ€ 206 | ```c++ 207 | 208 | string s = "abcde"; 209 | string t = "cdeab"; 210 | 211 | cout << (s.length() == t.length() && (s+s).find(t) != string::npos) << endl; 212 | 213 | ``` 214 | 215 | ### :memo: std::next_permutation āž”ļø 216 | ```c++ 217 | It gives the next lexicographically greater permutation. 218 | So, if the container is already the greatest permutation (descending order), it returns nothing. 219 | 220 | vector vec{1, 2, 3, 4}; 221 | 222 | if(next_permutation(begin(vec), end(vec))) 223 | cout << "Next permutation available" << endl; 224 | 225 | for(int &x : vec) 226 | cout << x << " "; 227 | 228 | //Output : 1, 2, 4, 3 229 | 230 | Also see : std::prev_permutation() - It gives just the previous lexicographically smaller permutation. 231 | But I have never encountered any question where it's required till now. So you can skip it. 232 | Leetcode - 31 : Next Permutation 233 | etc. 234 | ``` 235 | 236 | 237 | ### :memo: std::stringstream :fast_forward: 238 | ```c++ 239 | Usage: 240 | 1) Converting string to number 241 | 2) Count number of words in a string 242 | 243 | Example-1 244 | string s = "12345"; 245 | stringstream ss(s); 246 | 247 | // The object has the value 12345 and stream 248 | // it to the integer x 249 | int x = 0; 250 | ss >> x; 251 | cout << x; 252 | 253 | Exmaple-2 254 | stringstream s(ss); 255 | string word; // to store individual words 256 | 257 | int count = 0; 258 | while (s >> word) 259 | count++; 260 | cout << count; 261 | NOTE: It will tokenize words on the basis of ' ' (space by default) characters 262 | Example-3 263 | It can be used very well to extract numbers from string. 264 | string complex = "1+1i"; 265 | stringstream ss(complex); 266 | char justToSkip; 267 | int real, imag; 268 | ss >> real >> justToSkip >> imag >> justToSkip; 269 | cout << real << ", " << imag; //output : 1, 1 270 | 271 | Other application on this STL : 272 | Leetcode - 151 : Reverse Words in a String 273 | Leetcode - 186 : Reverse Words in a String II 274 | Leetcode - 557 : Reverse Words in a String III 275 | Leetcode - 1108 : Defanging an IP Address 276 | Leetcode - 1816 : Truncate Sentence 277 | Leetcode - 884 : Uncommon Words from Two Sentences 278 | Leetcode - 537 : Complex Number Multiplication (Example-3 above) 279 | Leetcode - 165 : Compare Version Numbers 280 | etc. 281 | ``` 282 | 283 | 284 | ### :memo: std::transform(InputIterator first1, InputIterator last1, OutputIterator result, UnaryOperation op) :robot: 285 | ```c++ 286 | Applies an operation sequentially to the elements of one (1) or 287 | two (2) ranges and stores the result in the range that begins at result. 288 | Uage : 289 | 1) Convert all letters of a string to lower case 290 | 2) Convert all letters of a string to upper case 291 | 292 | Example : 293 | string line = "Hello world, this is MIK"; 294 | 295 | transform(begin(line), end(line), begin(line), ::tolower); 296 | 297 | cout << line << endl; 298 | 299 | transform(begin(line), end(line), begin(line), ::toupper); 300 | 301 | cout << line << endl; 302 | 303 | ``` 304 | 305 | ### :memo: std::regex_replace :pager: 306 | ```c++ 307 | It converts a regular expression given by user to desired expression given by user. 308 | 309 | Example : 310 | Ex-1 - Remove all vowels from a string. 311 | string s = "mika"; 312 | auto rgx = regex("[aeiouAEIOU]"); 313 | cout << regex_replace(s, rgx, ""); 314 | 315 | Ex-2 - Replace all '.' to "[.]" 316 | string s = "1.2.3.4"; 317 | auto rgx = regex("\\."); 318 | regex_replace(s, rgx, "[.]"); 319 | 320 | Note : You can write smart regex for achieving amazing replacements. 321 | Qns on Leetcode: 322 | Leetcode - 1108 : Defanging an IP Address 323 | Leetcode - 1119 : Remove Vowels from a String 324 | etc. 325 | ``` 326 | 327 | ### :memo: std::count_if :1234: 328 | ```c++ 329 | counts the number of elements satisfying a given condition (given by comparator function or lambda) 330 | 331 | Example : 332 | vector vec{1, 3, 2, 0, 5, 0}; 333 | 334 | auto lambda = [&](const auto& i) { 335 | return i == 0; 336 | }; 337 | 338 | cout << count_if(begin(vec), end(vec), lambda); //output : 2 339 | 340 | Note : You can write any kind of lambda/comparator functions for matching your required condition 341 | Qns on Leetcode: 342 | Leetcode - 1773 : Count Items Matching a Rule 343 | etc. 344 | ``` 345 | 346 | ### :memo: std::copy_if :1234: 347 | ```c++ 348 | Copies the elements to a container 349 | how copy_if function works : in this function you have to pass four parameters 350 | copy_if(begin iterator , end iterator , destination , condition) 351 | 352 | eg : vector from_vec = {1,2,3,4,5,6,7,8,9,10}; 353 | vector to_vec; 354 | //here i want to copy all the number from from_vec vector to to_vec vector which are divisible by 2 . 355 | 356 | copy_if(from_vec.begin(), from_vec.end(), back_inserter(to_vec),[](int n){return n%2==0;}); 357 | 358 | for(auto it : to_vec) 359 | cout<> :1234: 370 | ```c++ 371 | Example-1 : 372 | //Let's say you want upper_bound for a variable timestamp, take it in a pair (because it's a vector of pair) 373 | pair ref = make_pair(timestamp, ""); 374 | 375 | auto lambda = [](const pair& p1, const pair& p2) { 376 | return p1.first < p2.first; 377 | }; 378 | 379 | auto it = upper_bound(begin(my_vector), end(my_vector), ref, lambda); 380 | 381 | Example-2 : 382 | //Let's say you want to find upper_bound of a value in a non-increasing vector. 383 | vector vec{1, 0, -1, -2} 384 | int idx = upper_bound(begin(vec), end(vec), 0, greater()) - begin(vec); 385 | Output will be index of -1 (i.e. 2) 386 | 387 | Qns on Leetcode: 388 | Leetcode - 981 : Time Based Key-Value Store 389 | Leetcode - 744 : Find Smallest Letter Greater Than Target 390 | Leetcode - 1351 : Count Negative Numbers in a Sorted Matrix 391 | 392 | ``` 393 | 394 | 395 | ### :memo: Writing lambda for unordered_map to make life simple :1234: 396 | ```c++ 397 | Example : 398 | //Let's say, you want to store different evaluate logic for different operator "+", "-", "*", "/" 399 | unordered_map > mp = { 400 | { "+" , [] (int a, int b) { return a + b; } }, 401 | { "-" , [] (int a, int b) { return a - b; } }, 402 | { "*" , [] (int a, int b) { return a * b; } }, 403 | { "/" , [] (int a, int b) { return a / b; } } 404 | }; 405 | 406 | //Simply use it like below :- 407 | int result = mp["+"](1, 2); //This will return 1+2 i.e. 3 408 | 409 | Qns on Leetcode: 150 410 | Leetcode - : Evaluate Reverse Polish Notation 411 | 412 | ``` 413 | 414 | 415 | 416 | 417 | ### :memo: std::set_difference and std::back_inserter :1234: 418 | ```c++ 419 | set_difference -> Copies the elements from the sorted s1 which are not found in the sorted s2 to a container in sorted order 420 | back_inserter -> Can be used to add elements to the end of a container 421 | Example : 422 | set st1, st2; 423 | vector v1; 424 | //Find difference in between set1 and set2 and put unique element of set1 in v1 425 | set_difference(begin(st1), end(st1), begin(st2), end(st2), back_inserter(v1)); 426 | 427 | Qns on Leetcode: 428 | Leetcode 2215 : Find the Difference of Two Arrays 429 | 430 | ``` 431 | 432 | 433 | ### :memo: std::hypot :triangular_ruler: 434 | ```c++ 435 | hypot -> Computes sqrt(x*x + y*y) (or sqrt(x*x + y*y + z*z) in C++17) safely, avoiding overflow/underflow. 436 | 437 | Example-1 : Compute hypotenuse of right triangle 438 | double x = 3.0, y = 4.0; 439 | double result = std::hypot(x, y); 440 | cout << result; //5.0 441 | 442 | Example-2 : Distance between two points (x1, y1) and (x2, y2) 443 | double x1 = 1, y1 = 2; 444 | double x2 = 4, y2 = 6; 445 | double dist = std::hypot(x2 - x1, y2 - y1); 446 | cout << dist; //5.0 447 | 448 | Example-3 (C++17) : 3D Distance 449 | double x = 1, y = 2, z = 2; 450 | double dist3D = std::hypot(x, y, z); 451 | cout << dist3D; //3.0 452 | 453 | Benefit : 454 | - Numerically stable (avoids overflow/underflow) 455 | - Cleaner than writing sqrt(x*x + y*y) 456 | - Works with float, double, long double 457 | 458 | Qns on Leetcode: 459 | Leetcode 812 : Largest Triangly Area 460 | --------------------------------------------------------------------------------