STL Algorithms

sort, find, transform, accumulate

Read: ~40 min 20 practice problems

1. Algorithms Operate on Iterator Ranges

Every algorithm takes a [first, last) half-open range. This decouples algorithms from containers:

algos.cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>

int main() {
    std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};

    std::sort(v.begin(), v.end());
    int sum = std::accumulate(v.begin(), v.end(), 0);
    auto it  = std::find(v.begin(), v.end(), 5);
    auto mx  = std::max_element(v.begin(), v.end());
    int cnt  = std::count_if(v.begin(), v.end(),
                              [](int x){ return x % 2 == 0; });

    std::cout << "sum=" << sum << ", max=" << *mx << ", evens=" << cnt << "\n";
    if (it != v.end()) std::cout << "5 found at " << (it - v.begin()) << "\n";
}

2. Most Used Algorithms

AlgorithmWhat it does
std::sortO(n log n) sort (typically introsort)
std::findLinear search, returns iter
std::find_ifLinear search with predicate
std::count_ifCount matching predicate
std::transformApply function, store result
std::accumulateReduce to a single value
std::for_eachApply side-effecting function
std::any_of / all_of / none_ofQuantifiers
std::min_element / max_elementFind extremes
std::reverseIn-place reverse
std::uniqueCollapse adjacent duplicates

3. Predicates with Lambdas

pred.cpp
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> v = {5, 2, 8, 1, 9, 3};

    std::sort(v.begin(), v.end(), [](int a, int b){ return a > b; });

    bool all_pos = std::all_of(v.begin(), v.end(),
                                  [](int x){ return x > 0; });

    auto first_big = std::find_if(v.begin(), v.end(),
                                     [](int x){ return x > 5; });

    std::cout << "all_pos=" << all_pos
              << ", first>5=" << (first_big != v.end() ? *first_big : -1) << "\n";
}

4. Transform & Accumulate

map_reduce.cpp
std::vector<int> v = {1,2,3,4,5};

std::vector<int> sq(v.size());
std::transform(v.begin(), v.end(), sq.begin(),
               [](int x){ return x * x; });

int total = std::accumulate(sq.begin(), sq.end(), 0);
// total = 1+4+9+16+25 = 55

5. Erase-Remove Idiom

Pre-C++20
v.erase(std::remove_if(v.begin(), v.end(), pred), v.end());
C++20
std::erase_if(v, pred);

6. Practice Problems

  1. Sort a vector ascending.
    ✨ Show Answer
    std::sort(v.begin(), v.end());
  2. Sum of squares.
    ✨ Show Answer
    int s = std::accumulate(v.begin(), v.end(), 0,
        [](int acc, int x){ return acc + x*x; });
  3. Count negatives.
    ✨ Show Answer
    std::count_if(v.begin(), v.end(), [](int x){ return x < 0; });
  4. Find first even.
    ✨ Show Answer
    std::find_if(v.begin(), v.end(), [](int x){ return x % 2 == 0; });
  5. Reverse in place.
    ✨ Show Answer
    std::reverse(v.begin(), v.end());
  6. Min and max in one call (C++11).
    ✨ Show Answer
    auto [mn, mx] = std::minmax_element(v.begin(), v.end());
  7. Check if any element is negative.
    ✨ Show Answer
    std::any_of(v.begin(), v.end(), [](int x){ return x < 0; });
  8. Apply x = x * 2 to every element.
    ✨ Show Answer
    std::transform(v.begin(), v.end(), v.begin(), [](int x){ return x*2; });

    (Or use std::for_each with auto&.)

  9. Sort vector of pairs by second element.
    ✨ Show Answer
    std::sort(v.begin(), v.end(),
        [](const auto& a, const auto& b){ return a.second < b.second; });
  10. Sum of doubles.
    ✨ Show Answer
    double s = std::accumulate(v.begin(), v.end(), 0.0); // note 0.0!

    If you write 0, accumulate uses int and truncates.

  11. Erase all 0s from vector.
    ✨ Show Answer
    v.erase(std::remove(v.begin(), v.end(), 0), v.end());
  12. Why is std::sort O(n log n)?
    ✨ Show Answer

    Standard requires it. Implementations typically use introsort (quicksort + heapsort fallback).

  13. Sort by string length.
    ✨ Show Answer
    std::sort(v.begin(), v.end(),
        [](const std::string& a, const std::string& b){ return a.size() < b.size(); });
  14. Use std::accumulate to multiply all elements.
    ✨ Show Answer
    std::accumulate(v.begin(), v.end(), 1, std::multiplies<>{});
  15. all_of: are all positive?
    ✨ Show Answer
    std::all_of(v.begin(), v.end(), [](int x){ return x > 0; });
  16. Why prefer std::sort over hand-coded sort?
    ✨ Show Answer

    Highly optimized, well-tested, future-proof. Library implementers spend years tuning these.

  17. Use std::iota to fill 0..9.
    ✨ Show Answer
    std::vector<int> v(10);
    std::iota(v.begin(), v.end(), 0); // 0,1,2,...,9
  18. C++20: erase even numbers in one call.
    ✨ Show Answer
    std::erase_if(v, [](int x){ return x % 2 == 0; });
  19. Why pass iterators, not container?
    ✨ Show Answer

    Decouples algorithm from container type and lets you operate on a sub-range. C++20 ranges (Module 35) finally close this gap.

  20. Use parallel sort (C++17).
    ✨ Show Answer
    #include <execution>
    std::sort(std::execution::par, v.begin(), v.end());

Summary

STL algorithms are tuned, generic, and operate on iterator ranges. Use them before writing raw loops. Lambdas make custom predicates trivial. Watch the type of the initial accumulator value (0 vs 0.0!). C++20 ranges and std::erase_if simplify the most common patterns.

Next Module → Iterators & Iterator Categories.