C++ STL 정리 (2편) — 알고리즘, 이터레이터, 유틸리티

2026. 6. 1. 16:05·블로그, 컴퓨터/Cheatsheets

C++ STL cheatsheet

1편에서 컨테이너를 정리했습니다. 2편에서는 알고리즘, 이터레이터, 람다, 그리고 C++17/20에서 추가된 유틸리티들을 다룹니다.


알고리즘 — <algorithm>

STL 알고리즘은 이터레이터 범위를 받아서 동작합니다. 컨테이너에 직접 묶이지 않아서 어떤 컨테이너에도 쓸 수 있습니다.

#include <algorithm>
#include <numeric>

정렬

std::vector<int> v = {3, 1, 4, 1, 5, 9, 2};

std::sort(v.begin(), v.end());                          // 오름차순
std::sort(v.begin(), v.end(), std::greater<int>());     // 내림차순
std::sort(v.begin(), v.end(), [](int a, int b) {        // 커스텀 비교
    return a > b;
});

std::stable_sort(v.begin(), v.end());   // 동일한 원소 순서 유지

// 부분 정렬 — 앞 n개만 정렬
std::partial_sort(v.begin(), v.begin() + 3, v.end());

// n번째 원소를 제자리에 (앞은 작은 것들, 뒤는 큰 것들)
std::nth_element(v.begin(), v.begin() + 3, v.end());

// 이미 정렬됐는지 확인
std::is_sorted(v.begin(), v.end());

탐색

// 선형 탐색
auto it = std::find(v.begin(), v.end(), 4);
if (it != v.end()) { /* 찾음 */ }

// 조건 탐색
auto it2 = std::find_if(v.begin(), v.end(), [](int x) {
    return x > 3;
});

// 이진 탐색 (정렬된 범위에서만)
bool found = std::binary_search(v.begin(), v.end(), 4);
auto lb = std::lower_bound(v.begin(), v.end(), 4);   // 4 이상 첫 번째
auto ub = std::upper_bound(v.begin(), v.end(), 4);   // 4 초과 첫 번째

// 원소 개수 세기
int cnt = std::count(v.begin(), v.end(), 1);
int cnt2 = std::count_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; });

// 최솟값/최댓값
auto min_it = std::min_element(v.begin(), v.end());
auto max_it = std::max_element(v.begin(), v.end());
auto [min_it2, max_it2] = std::minmax_element(v.begin(), v.end());

변환 / 복사

std::vector<int> src = {1, 2, 3, 4, 5};
std::vector<int> dst(5);

// 복사
std::copy(src.begin(), src.end(), dst.begin());

// 조건부 복사
std::copy_if(src.begin(), src.end(), dst.begin(), [](int x) {
    return x % 2 == 0;
});

// 변환
std::transform(src.begin(), src.end(), dst.begin(), [](int x) {
    return x * 2;
});

// 두 범위 변환
std::transform(src.begin(), src.end(), dst.begin(), dst.begin(),
    [](int a, int b) { return a + b; });

// 채우기
std::fill(v.begin(), v.end(), 0);
std::fill_n(v.begin(), 3, 99);

// 생성
std::generate(v.begin(), v.end(), [n=0]() mutable { return n++; });

// 교환
std::swap(v[0], v[1]);
std::iter_swap(v.begin(), v.end() - 1);

제거 / 정리

STL의 제거 함수들은 실제로 원소를 지우지 않고 "논리적으로 제거된" 원소를 뒤로 밀고 새 끝을 반환합니다. 실제 삭제는 erase와 조합합니다.

// erase-remove 관용구
v.erase(std::remove(v.begin(), v.end(), 3), v.end());

// 조건부 제거
v.erase(std::remove_if(v.begin(), v.end(), [](int x) {
    return x % 2 == 0;
}), v.end());

// 중복 제거 (정렬 후)
std::sort(v.begin(), v.end());
v.erase(std::unique(v.begin(), v.end()), v.end());

// 역순
std::reverse(v.begin(), v.end());

// 회전
std::rotate(v.begin(), v.begin() + 2, v.end());   // 2칸 왼쪽 회전

집합 연산 (정렬된 범위)

std::vector<int> a = {1, 2, 3, 4};
std::vector<int> b = {3, 4, 5, 6};
std::vector<int> result;

std::set_union(a.begin(), a.end(), b.begin(), b.end(),
    std::back_inserter(result));         // {1,2,3,4,5,6}

std::set_intersection(a.begin(), a.end(), b.begin(), b.end(),
    std::back_inserter(result));         // {3,4}

std::set_difference(a.begin(), a.end(), b.begin(), b.end(),
    std::back_inserter(result));         // {1,2}

수치 알고리즘 — <numeric>

#include <numeric>

std::vector<int> v = {1, 2, 3, 4, 5};

std::accumulate(v.begin(), v.end(), 0);         // 합계 = 15
std::accumulate(v.begin(), v.end(), 1,
    std::multiplies<int>());                    // 곱 = 120

std::partial_sum(v.begin(), v.end(), v.begin());   // 누적 합

std::iota(v.begin(), v.end(), 1);              // 1부터 순서대로 채우기

std::inner_product(a.begin(), a.end(), b.begin(), 0);  // 내적

이터레이터

종류

v.begin();    // 첫 번째 원소
v.end();      // 마지막 다음 (past-the-end)
v.rbegin();   // 역방향 첫 번째
v.rend();     // 역방향 마지막 다음
v.cbegin();   // const 이터레이터
v.cend();

이터레이터 어댑터

#include <iterator>

// back_inserter — push_back으로 삽입
std::vector<int> dst;
std::copy(src.begin(), src.end(), std::back_inserter(dst));

// front_inserter — push_front로 삽입 (deque, list)
std::copy(src.begin(), src.end(), std::front_inserter(lst));

// istream_iterator — 입력 스트림을 이터레이터로
std::istream_iterator<int> in(std::cin), eof;
std::vector<int> v(in, eof);

// ostream_iterator — 출력 스트림을 이터레이터로
std::copy(v.begin(), v.end(),
    std::ostream_iterator<int>(std::cout, " "));

advance / distance / next / prev

auto it = v.begin();
std::advance(it, 3);              // it를 3칸 앞으로
std::distance(v.begin(), it);     // 거리 = 3
auto it2 = std::next(it, 2);      // it에서 2칸 앞 (it는 안 바뀜)
auto it3 = std::prev(it, 1);      // it에서 1칸 뒤

람다와 함수형

람다 기본

auto add = [](int a, int b) { return a + b; };
add(3, 4);   // 7

// 반환 타입 명시
auto div = [](double a, double b) -> double { return a / b; };

// 캡처
int x = 10;
auto add_x = [x](int a) { return a + x; };     // 값 캡처
auto add_x2 = [&x](int a) { return a + x; };   // 참조 캡처
auto add_x3 = [=](int a) { return a + x; };    // 전체 값 캡처
auto add_x4 = [&](int a) { return a + x; };    // 전체 참조 캡처

// mutable — 값 캡처한 것 수정 허용
int count = 0;
auto inc = [count]() mutable { return ++count; };

<functional>

#include <functional>

// std::function — 함수, 람다, 함수 객체를 모두 담을 수 있는 래퍼
std::function<int(int, int)> op = [](int a, int b) { return a + b; };
op(3, 4);

// std::bind — 인수 고정
auto add5 = std::bind(std::plus<int>(), std::placeholders::_1, 5);
add5(3);    // 8

// 표준 함수 객체
std::plus<int>()
std::minus<int>()
std::multiplies<int>()
std::greater<int>()
std::less<int>()
std::negate<int>()
std::logical_and<bool>()

유틸리티 — C++17/20

pair / tuple

#include <utility>
#include <tuple>

std::pair<int, std::string> p = {1, "hello"};
p.first;
p.second;
auto [num, str] = p;    // 구조적 바인딩 (C++17)

std::tuple<int, double, std::string> t = {1, 3.14, "hi"};
std::get<0>(t);
std::get<1>(t);
auto [a, b, c] = t;     // 구조적 바인딩

optional — 값이 없을 수 있는 타입

#include <optional>

std::optional<int> find_value(bool found) {
    if (found) return 42;
    return std::nullopt;
}

auto result = find_value(true);
if (result) {
    std::cout << *result;          // 역참조
    std::cout << result.value();   // 또는 이렇게
}
result.value_or(0);                // 없으면 기본값

null 포인터나 -1 같은 sentinel 값 대신 쓸 수 있어서 의도가 명확해집니다.

variant — 타입 안전 union

#include <variant>

std::variant<int, double, std::string> v = 42;
v = 3.14;
v = "hello";

std::get<std::string>(v);           // "hello"
std::get<int>(v);                   // bad_variant_access 예외

std::holds_alternative<std::string>(v);   // true

std::visit([](auto& val) {
    std::cout << val;
}, v);

string_view — 문자열 비소유 참조

#include <string_view>

void print(std::string_view sv) {   // 복사 없이 문자열 참조
    std::cout << sv;
}

std::string s = "Hello, World";
print(s);                           // std::string도 가능
print("literal");                   // 리터럴도 가능
print(s.substr(0, 5));             // 부분 문자열도 가능

std::string_view sv = s;
sv.substr(0, 5);                    // 복사 없이 뷰만 반환

함수 인수로 문자열을 받을 때 const std::string& 대신 std::string_view를 쓰면 불필요한 복사를 줄일 수 있습니다.

span — 배열 비소유 뷰 (C++20)

#include <span>

void process(std::span<int> data) {
    for (auto& x : data) { ... }
}

std::vector<int> v = {1, 2, 3, 4, 5};
process(v);
process(std::span(v).subspan(1, 3));   // 부분 범위

ranges — 범위 기반 알고리즘 (C++20)

#include <ranges>
#include <algorithm>

std::vector<int> v = {3, 1, 4, 1, 5, 9, 2};

// ranges 버전은 컨테이너를 직접 받음
std::ranges::sort(v);
std::ranges::find(v, 4);

// 뷰 파이프라인
auto result = v
    | std::views::filter([](int x) { return x % 2 == 0; })
    | std::views::transform([](int x) { return x * 2; })
    | std::views::take(3);

for (auto x : result) { std::cout << x << " "; }

정리 표

알고리즘

함수 용도
sort / stable_sort 정렬
find / find_if 선형 탐색
binary_search / lower_bound 이진 탐색
count / count_if 개수 세기
transform 변환
copy / copy_if 복사
remove / remove_if + erase 제거
unique + erase 중복 제거
accumulate 합산
iota 순서대로 채우기

유틸리티

타입 용도
pair / tuple 여러 값 묶기
optional<T> 값이 없을 수 있는 타입
variant<T...> 타입 안전 union
string_view 문자열 비소유 참조
span<T> 배열 비소유 뷰
ranges:: / views:: 파이프라인 알고리즘
반응형
저작자표시 비영리 변경금지 (새창열림)

'블로그, 컴퓨터 > Cheatsheets' 카테고리의 다른 글

C++ STL 정리 (3편) — C++17/20 유틸리티  (0) 2026.06.01
C++ STL 정리 (1편) — 컨테이너  (0) 2026.06.01
GitHub Actions 정리 (2편) — 캐싱, Matrix, 재사용, 실전 패턴  (0) 2026.05.31
GitHub Actions 정리 (1편) — 개념, 워크플로우 구조, 트리거  (0) 2026.05.31
CMake 정리 (2편) — 서브디렉토리, 외부 라이브러리, 실용 패턴  (0) 2026.05.30
'블로그, 컴퓨터/Cheatsheets' 카테고리의 다른 글
  • C++ STL 정리 (3편) — C++17/20 유틸리티
  • C++ STL 정리 (1편) — 컨테이너
  • GitHub Actions 정리 (2편) — 캐싱, Matrix, 재사용, 실전 패턴
  • GitHub Actions 정리 (1편) — 개념, 워크플로우 구조, 트리거
생각사람
생각사람
지극히 사적인 연구실
  • 생각사람
    생각사람의 별장
    생각사람
  • 전체
    오늘
    어제
    • 분류 전체보기 (207)
      • 금융 (57)
        • 주식 공부 (11)
        • 파생상품 입문 (17)
        • 파생상품 기초 (15)
        • 파생상품 실전 (14)
      • 블로그, 컴퓨터 (83)
        • 프로그래밍 (16)
        • DevOps (8)
        • AI, RL, ML, ... (5)
        • 애드센스, SEO (23)
        • 임베디드 (3)
        • 컴퓨터 관련 (7)
        • Cheatsheets (21)
      • 다른 공부들 (67)
        • 읽고 쓰기 (18)
        • 수학 (15)
        • 물리 (9)
        • 사진 공부 (25)
  • 인기 글

  • 최근 글

  • 최근 댓글

  • 태그

    CheatSheet
    cmake
    선형대수학
    c++
    구글 애드센스
    스트래들
    스트랭글
    깃허브
    AI
    슈뢰딩거 방정식
    깃
    GIT
    소니 a6000
    코딩
    웹크롤러
    Kreyszig
    c
    프로그래밍
    github
    독후감
    옵션
    파생상품
    행렬
    version control
    옵션 투자
    선물 옵션
    공업수학
    벡터
    오펜하이머
    양자역학
  • hELLO· Designed By정상우.v4.10.6
생각사람
C++ STL 정리 (2편) — 알고리즘, 이터레이터, 유틸리티
상단으로

티스토리툴바