C++ STL Algorithms Basics | sort, find, count, transform, accumulate
이 글의 핵심
STL algorithms from <algorithm> and <numeric>: sort, search, aggregate, transform—with lambdas and correct complexity choices.
Introduction: Manual loops bred bugs
“Sorting, searching, summing—I rewrite loops every time”
Hand-rolled bubble sort, linear search, and sum loops are error-prone (off-by-one, invalid iterators).
STL algorithms take half-open ranges [first, last) and a predicate or operation—usually clearer and well-tested.
STL rewrite of the naive example:
#include <algorithm>
#include <numeric>
std::vector<int> vec = {5, 2, 8, 1, 9};
std::sort(vec.begin(), vec.end());
auto it = std::find(vec.begin(), vec.end(), 8);
int index = (it != vec.end()) ? static_cast<int>(std::distance(vec.begin(), it)) : -1;
int sum = std::accumulate(vec.begin(), vec.end(), 0);
flowchart TB
subgraph problem["Common mistakes"]
P1[Manual loops → index bugs]
P2["Sorted data but linear find"]
P3[remove without erase]
P4[Wrong comparator]
end
subgraph solution["Fix"]
S1[STL algorithms]
S2[lower_bound / binary_search]
S3[erase-remove idiom]
S4[Strict weak ordering]
end
P1 --> S1
P2 --> S2
P3 --> S3
P4 --> S4
Table of contents
- Problem scenarios
- sort
- find
- count and accumulate
- transform
- Examples
- Common errors
- Best practices
- Production patterns
- Checklist
1. Problem scenarios
- Big data sorted with O(n²) → use
std::sortO(n log n) - Sorted range search with
find→ uselower_boundO(log n) - Counting with manual loops →
count_if removewithouterase→ size unchanged → erase-remove- Product with
accumulate(..., 0, multiplies)— wrong; use initial value1for products
2. sort
std::sort(vec.begin(), vec.end());
std::sort(vec.begin(), vec.end(), std::greater<int>());
Custom comparator: strict weak ordering—typically return a < b for ascending.
stable_sort preserves relative order of equal elements.
3. find
find: linear search for valuefind_if: first element satisfying predicate- Sorted range:
binary_search,lower_bound,upper_bound
4. count and accumulate
int n2 = std::count(vec.begin(), vec.end(), 2);
int evens = std::count_if(vec.begin(), vec.end(), [](int x){ return x % 2 == 0; });
int sum = std::accumulate(vec.begin(), vec.end(), 0);
int prod = std::accumulate(vec.begin(), vec.end(), 1, std::multiplies<int>());
String concatenation: start from std::string(), not "" as const char* (avoid subtle issues).
5. transform
Unary: transform each element to output range. In-place: output vec.begin().
Binary: combine two sequences element-wise (same length discipline).
7. Common errors
- Dereference
findresult without!= end() removeonly—musterasefromnew_endtoend()transformoutput range too small—size orback_inserter- Product
accumulatewith initial 0 lower_boundon unsorted data → meaningless- Comparator
<=forsort→ not a strict weak ordering
8. Best practices
- Use
const Person&in predicates for large structs reservebeforeback_inserterwhen size known- Check
is_sortedbefore binary search if unsure
9. Production patterns
- erase-remove / erase-remove_if
- sort + unique + erase for duplicates
minmax_elementfor min and max in one passmergeon sorted inputs
10. Checklist
- Sorted? → binary search APIs
-
remove→ pairederase -
find→ checkend -
accumulateproduct → init1
FAQ
Default toolkit?
A. sort, find/find_if, count_if, accumulate, transform cover most loops.
Sorted vector vs set?
A. Many searches, few inserts: sorted vector + binary search can be faster/more cache-friendly. Frequent inserts/erases: set/map.
C++20 ranges?
A. std::ranges::sort(vec) and friends reduce iterator noise—see cppreference.
One-line summary: Prefer STL algorithms over ad-hoc loops; pair remove with erase, and use lower_bound on sorted data.
Previous: vector basics
Next: STL algorithms deep dive
Keywords
C++, STL, algorithm, std::sort, std::find, std::transform, std::accumulate, lambda, predicate
References
Related posts
- STL algorithms patterns
- Lambda expressions
- vector basics