핵심 정리
cpp
#include <algorithm>
#include <vector>
std::vector<int> v{7, 2, 9, 4, 1};
std::sort(v.begin(), v.end()); // 오름차순 정렬
std::sort(v.begin(), v.end(), std::greater<int>{}); // 내림차순 정렬
auto it = std::find(v.begin(), v.end(), 4); // 값 탐색
auto it2 = std::find_if(v.begin(), v.end(),
[](int x){ return x > 5; }); // 조건 탐색문법
어떤 알고리즘을 먼저 떠올리면 되나
| 상황 | 먼저 떠올릴 것 |
|---|---|
| 정렬 | std::sort |
| 값 찾기 | std::find |
| 조건으로 찾기 | std::find_if |
| 조건 검사 | all_of, any_of, none_of |
| 변환 | std::transform |
| 삭제 | remove_if + erase |
설계 원칙 — 컨테이너와 알고리즘 분리
표준 알고리즘은 컨테이너 자체가 아니라 반복자 범위 [begin, end)를 받아 동작합니다. 덕분에 같은 알고리즘을 vector, array, deque 등 어떤 컨테이너에도 재사용할 수 있습니다.
cpp
std::array<int, 5> arr{5, 3, 1, 4, 2};
std::sort(arr.begin(), arr.end()); // vector든 array든 동일하게 사용탐색과 조건 검사
cpp
// 조건을 만족하는 첫 번째 요소
auto it = std::find_if(v.begin(), v.end(), [](int x){ return x % 2 == 0; });
// 전체 / 일부 / 없음 검사
bool allPos = std::all_of(v.begin(), v.end(), [](int x){ return x > 0; });
bool anyBig = std::any_of(v.begin(), v.end(), [](int x){ return x > 8; });
bool noneNeg = std::none_of(v.begin(), v.end(), [](int x){ return x < 0; });
// 조건 만족 개수
int evens = std::count_if(v.begin(), v.end(), [](int x){ return x % 2 == 0; });변환과 집계
cpp
std::vector<int> src{1, 2, 3, 4, 5};
std::vector<int> dst(src.size());
// 각 요소 변환 후 출력 범위에 저장
std::transform(src.begin(), src.end(), dst.begin(),
[](int x){ return x * x; }); // dst = {1,4,9,16,25}
// 누적 합계 — <numeric> 헤더
#include <numeric>
int sum = std::accumulate(src.begin(), src.end(), 0);
int product = std::accumulate(src.begin(), src.end(), 1,
std::multiplies<int>{}); // 120
// 최솟값 / 최댓값 위치
auto minIt = std::min_element(src.begin(), src.end());
auto maxIt = std::max_element(src.begin(), src.end());수정과 정리
cpp
// erase-remove idiom — 조건 요소 완전 삭제
v.erase(std::remove_if(v.begin(), v.end(),
[](int x){ return x % 2 == 0; }), v.end());
// 조건 만족 요소만 복사
std::vector<int> out;
std::copy_if(src.begin(), src.end(), std::back_inserter(out),
[](int x){ return x > 2; }); // out = {3,4,5}
// 채우기 / 연속값 채우기
std::fill(v.begin(), v.end(), 0);
std::iota(v.begin(), v.end(), 1); // 1,2,3,... (<numeric>)cpp
// ❌ remove_if만 호출하면 컨테이너 크기는 그대로
std::remove_if(v.begin(), v.end(), [](int x){ return x % 2 == 0; });
// ✅ erase와 이어 써야 실제 삭제
v.erase(std::remove_if(v.begin(), v.end(),
[](int x){ return x % 2 == 0; }), v.end());C++20 ranges — 더 읽기 좋은 파이프라인
cpp
#include <ranges>
std::ranges::sort(v); // begin()/end() 생략 가능
auto result = v
| std::views::filter([](int x){ return x % 2 == 0; })
| std::views::transform([](int x){ return x * x; });
// 지연 평가 — 실제 계산은 열거 시점에만 발생체크포인트
| 함수 | 역할 |
|---|---|
sort | 범위 정렬 (평균 O(n log n)) |
find / find_if | 값 / 조건 탐색, 반복자 반환 |
all_of / any_of / none_of | 조건 일괄 검사 |
count_if | 조건 만족 개수 |
transform | 각 요소 변환 후 출력 범위에 저장 |
accumulate | 누적 연산 (<numeric>) |
remove_if + erase | 조건 요소 실제 삭제 (erase-remove idiom) |
copy_if | 조건 만족 요소만 복사 |
min_element / max_element | 최솟/최댓값 반복자 반환 |
주의할 점
std::remove_if는 요소를 실제로 삭제하지 않고 범위 뒤쪽으로 밀어낸 뒤 새 끝 반복자만 반환합니다. 컨테이너에서 완전히 제거하려면 반드시 erase를 이어 호출해야 합니다.
accumulate와 iota는 <numeric> 헤더에 있습니다. <algorithm>과 다른 헤더임에 주의하세요.
참고 링크
1 sources