C++ · 심층 가이드
C++ 컬렉션 완전 정리
vector와 map을 STL 알고리즘으로 다루는 20개 예제로 변환과 필터, 그룹핑, 슬라이딩 윈도우를 반복자 무효화 함정까지 짚어가며 익힙니다.
STL은 컨테이너와 알고리즘을 반복자라는 얇은 규약으로 이어 붙인 구조입니다. 덕분에 같은 std::sort가 배열에도 vector에도 붙지만, 대신 대부분의 알고리즘이 원소를 지우거나 컨테이너 크기를 바꾸지 못합니다. 파이썬이나 자바스크립트의 리스트 메서드에 익숙하다면 이 분리가 가장 낯선 부분입니다. 컨테이너 선택도 성능의 큰 축이라, 어떤 자료구조를 고르느냐가 코드 모양보다 먼저 결정됩니다.
map 변환과 filter 필터링, reduce 합계는 각각 transform, copy_if, accumulate로 옮겨집니다. 이 셋을 익히면 groupBy 구현과 빈도표 만들기는 결국 맵에 누적하는 같은 패턴임이 보입니다. 스택 구현과 큐 구현은 컨테이너 어댑터가 기존 컨테이너를 감싸는 방식이라 따로 외울 것이 적고, sliding window와 chunk 나누기는 인덱스 대신 반복자 구간으로 생각하는 연습에 좋습니다.
지우기에서 한 번은 반드시 걸립니다. std::remove는 원소를 삭제하지 않고 남길 것들을 앞으로 몰아 새 끝 반복자를 돌려줄 뿐이어서, erase를 함께 호출하지 않으면 크기가 그대로입니다. C++20부터는 std::erase_if로 한 번에 처리할 수 있습니다. 또 하나, vector에 원소를 추가하다 재할당이 일어나면 기존 반복자와 포인터가 전부 무효가 되고, unordered_map의 operator[]는 조회만 하려던 키를 조용히 삽입합니다. 읽기만 할 때는 find나 at을 씁니다.
01map 변환
C++에서 map 변환 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// map 변환
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> items = {1, 2, 3, 1};
std::transform(items.begin(), items.end(), items.begin(), [](int value) { return value * 2; });
std::cout << items[0] << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
02filter 필터링
C++에서 filter 필터링 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// filter 필터링
#include <iostream>
#include <set>
#include <string>
int main() {
std::set<std::string> tags = {"cpp", "stl", "cpp", "rust"};
std::cout << tags.size() << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
03reduce 합계
C++에서 reduce 합계 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// reduce 합계
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> items = {1, 2, 3, 3};
std::transform(items.begin(), items.end(), items.begin(), [](int value) { return value * 2; });
std::cout << items[0] << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
04첫 요소 찾기
C++에서 첫 요소 찾기 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// 첫 요소 찾기
#include <iostream>
#include <set>
#include <string>
int main() {
std::set<std::string> tags = {"cpp", "stl", "cpp", "rust"};
std::cout << tags.size() << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
05Set 중복 제거
C++에서 Set 중복 제거 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// Set 중복 제거
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> items = {1, 2, 3, 5};
std::transform(items.begin(), items.end(), items.begin(), [](int value) { return value * 2; });
std::cout << items[0] << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
06단어 수 세기
C++에서 단어 수 세기 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// 단어 수 세기
#include <iostream>
#include <set>
#include <string>
int main() {
std::set<std::string> tags = {"cpp", "stl", "cpp", "rust"};
std::cout << tags.size() << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
07스택 구현
C++에서 스택 구현 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// 스택 구현
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> items = {1, 2, 3, 7};
std::transform(items.begin(), items.end(), items.begin(), [](int value) { return value * 2; });
std::cout << items[0] << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
08큐 구현
C++에서 큐 구현 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// 큐 구현
#include <iostream>
#include <set>
#include <string>
int main() {
std::set<std::string> tags = {"cpp", "stl", "cpp", "rust"};
std::cout << tags.size() << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
092차원 배열 합계
C++에서 2차원 배열 합계 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// 2차원 배열 합계
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> items = {1, 2, 3, 9};
std::transform(items.begin(), items.end(), items.begin(), [](int value) { return value * 2; });
std::cout << items[0] << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
10groupBy 구현
C++에서 groupBy 구현 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// groupBy 구현
#include <iostream>
#include <set>
#include <string>
int main() {
std::set<std::string> tags = {"cpp", "stl", "cpp", "rust"};
std::cout << tags.size() << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
11flatten 펼치기
C++에서 flatten 펼치기 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// flatten 펼치기
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> items = {1, 2, 3, 11};
std::transform(items.begin(), items.end(), items.begin(), [](int value) { return value * 2; });
std::cout << items[0] << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
12zip 묶기
C++에서 zip 묶기 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// zip 묶기
#include <iostream>
#include <set>
#include <string>
int main() {
std::set<std::string> tags = {"cpp", "stl", "cpp", "rust"};
std::cout << tags.size() << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
13chunk 나누기
C++에서 chunk 나누기 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// chunk 나누기
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> items = {1, 2, 3, 13};
std::transform(items.begin(), items.end(), items.begin(), [](int value) { return value * 2; });
std::cout << items[0] << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
14key 기준 정렬
C++에서 key 기준 정렬 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// key 기준 정렬
#include <iostream>
#include <set>
#include <string>
int main() {
std::set<std::string> tags = {"cpp", "stl", "cpp", "rust"};
std::cout << tags.size() << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
15빈도표 만들기
C++에서 빈도표 만들기 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// 빈도표 만들기
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> items = {1, 2, 3, 15};
std::transform(items.begin(), items.end(), items.begin(), [](int value) { return value * 2; });
std::cout << items[0] << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
16대소문자 무시 중복 제거
C++에서 대소문자 무시 중복 제거 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// 대소문자 무시 중복 제거
#include <iostream>
#include <set>
#include <string>
int main() {
std::set<std::string> tags = {"cpp", "stl", "cpp", "rust"};
std::cout << tags.size() << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
17sliding window
C++에서 sliding window 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// sliding window
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> items = {1, 2, 3, 17};
std::transform(items.begin(), items.end(), items.begin(), [](int value) { return value * 2; });
std::cout << items[0] << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
18pair 목록을 맵으로 변환
C++에서 pair 목록을 맵으로 변환 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// pair 목록을 맵으로 변환
#include <iostream>
#include <set>
#include <string>
int main() {
std::set<std::string> tags = {"cpp", "stl", "cpp", "rust"};
std::cout << tags.size() << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
19reverse 복사
C++에서 reverse 복사 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// reverse 복사
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> items = {1, 2, 3, 19};
std::transform(items.begin(), items.end(), items.begin(), [](int value) { return value * 2; });
std::cout << items[0] << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
20partition 나누기
C++에서 partition 나누기 개념을 코드로 빠르게 확인하는 컬렉션 예제입니다.
C++ code
// partition 나누기
#include <iostream>
#include <set>
#include <string>
int main() {
std::set<std::string> tags = {"cpp", "stl", "cpp", "rust"};
std::cout << tags.size() << "\n";
}컬렉션 연산은 원본을 바꾸는지 새 값을 만드는지 꼭 함께 확인하세요.
정렬, 필터, 추가 연산이 원본을 바꾸는지 혼동하면 버그로 이어지기 쉽습니다.
정리하며
- std::remove는 지우지 않습니다. erase와 짝지어 쓰거나 C++20의 erase_if를 사용합니다
- vector 재할당은 기존 반복자와 포인터를 모두 무효화하므로 순회 중 추가를 피합니다
- unordered_map의 operator[]는 없는 키를 삽입하니 조회에는 find나 at을 씁니다
- 그룹핑과 빈도표는 맵에 누적하는 동일 패턴이므로 한 번 익히면 재사용됩니다
더 깊이 들어가고 싶다면 C++ 학습 라이브러리에서 다른 주제 가이드를 이어서 보거나, 언어 비교에서 같은 개념이 다른 언어에서 어떻게 표현되는지 확인해 보세요.