STL Algorithms
sort, find, transform, accumulate
1. Algorithms Operate on Iterator Ranges
Every algorithm takes a [first, last) half-open range. This decouples algorithms from containers:
#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
| Algorithm | What it does |
|---|---|
std::sort | O(n log n) sort (typically introsort) |
std::find | Linear search, returns iter |
std::find_if | Linear search with predicate |
std::count_if | Count matching predicate |
std::transform | Apply function, store result |
std::accumulate | Reduce to a single value |
std::for_each | Apply side-effecting function |
std::any_of / all_of / none_of | Quantifiers |
std::min_element / max_element | Find extremes |
std::reverse | In-place reverse |
std::unique | Collapse adjacent duplicates |
3. Predicates with Lambdas
#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
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
v.erase(std::remove_if(v.begin(), v.end(), pred), v.end());
C++20
std::erase_if(v, pred);
6. Practice Problems
- Sort a vector ascending.
✨ Show Answer
std::sort(v.begin(), v.end()); - Sum of squares.
✨ Show Answer
int s = std::accumulate(v.begin(), v.end(), 0, [](int acc, int x){ return acc + x*x; }); - Count negatives.
✨ Show Answer
std::count_if(v.begin(), v.end(), [](int x){ return x < 0; }); - Find first even.
✨ Show Answer
std::find_if(v.begin(), v.end(), [](int x){ return x % 2 == 0; }); - Reverse in place.
✨ Show Answer
std::reverse(v.begin(), v.end()); - Min and max in one call (C++11).
✨ Show Answer
auto [mn, mx] = std::minmax_element(v.begin(), v.end()); - Check if any element is negative.
✨ Show Answer
std::any_of(v.begin(), v.end(), [](int x){ return x < 0; }); - Apply
x = x * 2to every element.✨ Show Answer
std::transform(v.begin(), v.end(), v.begin(), [](int x){ return x*2; });(Or use
std::for_eachwithauto&.) - 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; }); - Sum of doubles.
✨ Show Answer
double s = std::accumulate(v.begin(), v.end(), 0.0); // note 0.0!If you write
0, accumulate usesintand truncates. - Erase all 0s from vector.
✨ Show Answer
v.erase(std::remove(v.begin(), v.end(), 0), v.end()); - Why is std::sort O(n log n)?
✨ Show Answer
Standard requires it. Implementations typically use introsort (quicksort + heapsort fallback).
- 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(); }); - Use std::accumulate to multiply all elements.
✨ Show Answer
std::accumulate(v.begin(), v.end(), 1, std::multiplies<>{}); - all_of: are all positive?
✨ Show Answer
std::all_of(v.begin(), v.end(), [](int x){ return x > 0; }); - Why prefer std::sort over hand-coded sort?
✨ Show Answer
Highly optimized, well-tested, future-proof. Library implementers spend years tuning these.
- Use
std::iotato fill 0..9.✨ Show Answer
std::vector<int> v(10); std::iota(v.begin(), v.end(), 0); // 0,1,2,...,9 - C++20: erase even numbers in one call.
✨ Show Answer
std::erase_if(v, [](int x){ return x % 2 == 0; }); - 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.
- 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.