C++ Iterators, STL Algorithms: sort, find, transform, accumulate Masterclass
Welcome to Phase 15: Iterators & Algorithms! Iterators are the glue between containers and algorithms. The STL algorithm library provides over 100 generic algorithms (sort, find, transform, accumulateβ¦) that work on any container via iterators β enabling powerful, reusable, and highly optimized code.
| Category | Supports | Example Container |
|---|---|---|
| Input Iterator | Read once, forward only | std::istream_iterator |
| Output Iterator | Write once, forward only | std::ostream_iterator |
| Forward Iterator | Read/Write, forward only | std::forward_list |
| Bidirectional | Read/Write, forward & backward | std::list, std::set |
| Random Access | Full arithmetic (+, -, []) | std::vector, std::array |
| Contiguous (C++20) | Random access + contiguous memory | std::vector, std::string |
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <string>
int main() {
std::vector<int> nums{5, 2, 8, 1, 9, 3, 7, 4, 6};
// sort ascending
std::sort(nums.begin(), nums.end());
std::cout << "sorted: ";
for (int n : nums) std::cout << n << " ";
std::cout << "
";
// sort descending with custom comparator
std::sort(nums.begin(), nums.end(), std::greater<int>{});
std::cout << "descend: ";
for (int n : nums) std::cout << n << " ";
std::cout << "
";
// find
auto it = std::find(nums.begin(), nums.end(), 7);
if (it != nums.end())
std::cout << "found 7 at index: " << std::distance(nums.begin(), it) << "
";
// count_if
int evenCount = std::count_if(nums.begin(), nums.end(),
[](int n){ return n % 2 == 0; });
std::cout << "even count: " << evenCount << "
";
// transform: square each element into new vector
std::vector<int> squares(nums.size());
std::transform(nums.begin(), nums.end(), squares.begin(),
[](int n){ return n * n; });
std::cout << "squares: ";
for (int s : squares) std::cout << s << " ";
std::cout << "
";
// accumulate: sum all
int total = std::accumulate(nums.begin(), nums.end(), 0);
std::cout << "sum: " << total << "
";
// min/max element
auto [mn, mx] = std::minmax_element(nums.begin(), nums.end());
std::cout << "min=" << *mn << " max=" << *mx << "
";
// remove_if + erase idiom
nums.erase(std::remove_if(nums.begin(), nums.end(),
[](int n){ return n % 2 == 0; }),
nums.end());
std::cout << "after removing evens: ";
for (int n : nums) std::cout << n << " ";
std::cout << "
";
// binary search (on sorted range)
std::vector<int> sorted{1,2,3,4,5,6,7,8,9};
bool found = std::binary_search(sorted.begin(), sorted.end(), 5);
std::cout << "binary_search(5): " << std::boolalpha << found << "
";
auto lb = std::lower_bound(sorted.begin(), sorted.end(), 5);
std::cout << "lower_bound(5) index: " << std::distance(sorted.begin(), lb) << "
";
return 0;
}
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main() {
std::vector<int> v{1,2,3,4,5};
// reverse in-place
std::reverse(v.begin(), v.end());
std::cout << "reversed: ";
for (int x : v) std::cout << x << " ";
std::cout << "
";
// copy to another container
std::vector<int> dest(v.size());
std::copy(v.begin(), v.end(), dest.begin());
// fill with a value
std::vector<int> zeros(5);
std::fill(zeros.begin(), zeros.end(), 0);
// for_each with side effects
std::for_each(v.begin(), v.end(), [](int& x){ x *= 2; });
std::cout << "doubled: ";
for (int x : v) std::cout << x << " ";
std::cout << "
";
// copy to ostream
std::cout << "ostream copy: ";
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "
";
return 0;
}
Q1: What is the erase-remove idiom?
std::remove_if moves matching elements to the end and returns an iterator to the new logical end. Then erase() actually removes them. They must be combined because algorithms don't change container size.
Q2: Difference between sort and stable_sort?
std::sort is O(n log n) but doesn't preserve relative order of equal elements. std::stable_sort preserves relative order of equal elements (slightly more memory and time).
Q3: What does std::distance do?
std::distance(first, last) returns the number of hops between two iterators. For random-access iterators it's O(1), for others O(n).
Q4: What is std::back_inserter?
std::back_inserter(container) returns an output iterator that calls push_back() on each assignment β used with std::copy to append to a container.
Q5: What is std::partition?
std::partition(begin, end, pred) reorders elements so those satisfying pred come first. Returns iterator to the first element NOT satisfying pred.