C++ Algorithms
The header algorithm contains dozens of ready-made algorithms, and numeric adds a few for numbers. They work on any container through iterators, usually begin() and end(). Using them instead of hand-written loops makes code shorter, clearer and less buggy.
Sorting, searching and counting
#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
int main() {
std::vector<int> v = {42, 7, 19, 88, 3, 19};
std::sort(v.begin(), v.end());
for (int x : v) std::cout << x << " ";
std::cout << "\n";
auto it = std::find(v.begin(), v.end(), 88);
if (it != v.end()) std::cout << "88 found at position " << (it - v.begin()) << "\n";
std::cout << "19 appears " << std::count(v.begin(), v.end(), 19) << " times\n";
std::cout << "sum " << std::accumulate(v.begin(), v.end(), 0) << "\n";
std::cout << "max " << *std::max_element(v.begin(), v.end()) << "\n";
return 0;
}3 7 19 19 42 88 88 found at position 5 19 appears 2 times sum 178 max 88
With lambdas
Many algorithms take a condition or a rule as a lambda: count_if, find_if, sort with a custom order, transform and remove_if.
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
#include <vector>
int main() {
std::vector<int> marks = {45, 72, 88, 39, 91};
int passed = std::count_if(marks.begin(), marks.end(), [](int m) { return m >= 50; });
std::cout << passed << " passed\n";
auto first = std::find_if(marks.begin(), marks.end(), [](int m) { return m > 80; });
std::cout << "first above 80: " << *first << "\n";
std::string word = "hello";
std::transform(word.begin(), word.end(), word.begin(), [](unsigned char c) { return std::toupper(c); });
std::cout << word << "\n";
std::vector<int> v = {1, -2, 3, -4, 5};
v.erase(std::remove_if(v.begin(), v.end(), [](int x) { return x < 0; }), v.end());
for (int x : v) std::cout << x << " ";
std::cout << "\n";
return 0;
}3 passed first above 80: 88 HELLO 1 3 5
remove_if moves the kept elements to the front and returns where the rest starts; erase then cuts them off. This "erase-remove" pair is a classic; C++20's std::erase_if(v, ...) does both.
Other useful algorithms
| Algorithm | Does |
|---|---|
std::reverse | reverses the order |
std::binary_search | fast search in a sorted range |
std::unique | removes neighbouring duplicates (sort first) |
std::fill, std::iota | fills with one value, or with 1, 2, 3, … |
std::all_of, std::any_of, std::none_of | test a condition on all elements |
std::min, std::max, std::minmax_element | smallest and largest |
Ranges (C++20)
The ranges versions take the whole container instead of a pair of iterators, and views can filter and transform lazily:
#include <algorithm>
#include <iostream>
#include <ranges>
#include <vector>
int main() {
std::vector<int> v = {5, 2, 8, 1, 9, 4};
std::ranges::sort(v);
for (int x : v | std::views::filter([](int x) { return x % 2 == 0; })
| std::views::transform([](int x) { return x * x; })) {
std::cout << x << " ";
}
std::cout << "\n";
return 0;
}4 16 64
Why use algorithms
A named algorithm says what the code does: std::count_if is clearer than a loop with a counter, and it is tested and fast. Most algorithms take a range as two iterators, begin and end, so the same function works with vectors, arrays, lists and strings. Remember that std::remove does not shrink a container; combine it with erase, or use C++20's std::erase_if.
Practice exercises
- Sort a vector of words alphabetically, then by length with a lambda.
- Use
std::any_ofto check whether a vector contains a negative number. - Remove duplicates from a vector with
sort,uniqueanderase.