C++의 강력한 표준 템플릿 라이브러리인 STL(Standard Template Library)의 기초를 학습했다. 데이터를 효율적으로 관리하는 컨테이너(주로 vector와 map), 데이터를 처리하는 알고리즘(sort, find), 그리고 이 둘을 연결하는 반복자의 세 가지 핵심 구성 요소를 배웠다. 🚀 STL을 활용하면 복잡한 자료구조나 알고리즘을 직접 구현할 필요 없이, 생산성 높고 안정적인 코드를 작성할 수 있다는 점을 깨달았다.
vector와 map 컨테이너의 선언 및 기본 사용법 익히기sort, find 알고리즘을 활용하여 데이터를 처리하기int, string, 사용자 정의 class 등 어떤 타입의 데이터든 담고 처리할 수 있다.vector: 배열처럼 순차적인 데이터를 저장하는 동적 배열 컨테이너. 크기가 자동으로 조절된다.map: Key와 Value를 하나의 쌍으로 저장하는 연관 컨테이너. Key를 기준으로 자동 정렬되며, Key는 중복될 수 없다.sort: 지정된 범위의 원소를 정렬한다. (기본은 오름차순)find: 지정된 범위에서 특정 값을 찾아 그 위치의 반복자를 반환한다.++(다음 원소로 이동), *(역참조하여 값 접근) 등의 연산을 통해 원소를 순회하고 접근할 수 있게 해준다.begin(): 컨테이너의 첫 번째 원소를 가리키는 반복자를 반환한다.end(): 컨테이너의 마지막 원소 바로 다음을 가리키는 반복자를 반환한다.rbegin(), rend(): 역순 순회를 위한 반복자다. (reverse begin, reverse end)#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <algorithm> // sort, find 함수를 사용하기 위해 필수
int main() {
// ===== 1. 벡터(Vector) 사용 예제 =====
std::cout << "--- Vector Example ---" << std::endl;
// int 타입을 저장하는 vector 컨테이너 생성 및 초기화
std::vector<int> vec = {50, 20, 40, 10, 30};
// push_back: 벡터의 맨 뒤에 원소 추가
vec.push_back(60); // {50, 20, 40, 10, 30, 60}
// 반복자를 사용한 순회 및 출력
std::cout << "Original Vector: ";
// auto 키워드로 컴파일러가 반복자 타입을 추론하게 함
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " "; // *it: 반복자가 가리키는 원소의 값
}
std::cout << std::endl;
// 알고리즘: sort를 사용하여 벡터를 정렬. 시작 반복자와 끝 반복자를 인자로 받음
std::sort(vec.begin(), vec.end());
std::cout << "Sorted Vector: ";
// 범위 기반 for문: 더 간결하게 순회 가능
for (int num : vec) {
std::cout << num << " ";
}
std::cout << std::endl << std::endl;
// ===== 2. 맵(Map) 사용 예제 =====
std::cout << "--- Map Example ---" << std::endl;
// string을 Key로, int를 Value로 갖는 map 컨테이너 생성
std::map<std::string, int> studentScores;
// [] 연산자를 이용한 삽입 (Key가 없으면 새로 생성, 있으면 값 수정)
studentScores["Charlie"] = 85;
studentScores["Alice"] = 95;
studentScores["Bob"] = 90;
// map은 Key를 기준으로 자동 오름차순 정렬됨
std::cout << "Student Scores (Sorted by Name):" << std::endl;
for (const auto& pair : studentScores) {
// pair.first: Key, pair.second: Value
std::cout << pair.first << ": " << pair.second << std::endl;
}
// 알고리즘: find를 사용하여 특정 Key 찾기
std::string target = "Bob";
auto it = studentScores.find(target); // 'Bob' 키를 찾음
// find는 성공 시 해당 위치의 반복자를, 실패 시 end() 반복자를 반환
if (it != studentScores.end()) {
std::cout << "\nFound! " << it->first << "'s score is " << it->second << std::endl;
} else {
std::cout << "\n" << target << " not found." << std::endl;
}
return 0;
}
sort나 find 같은 알고리즘 함수를 사용하면서 #include <algorithm> 헤더를 추가하는 것을 잊어 컴파일 에러를 만났다. STL의 기능들은 각기 다른 헤더 파일에 정의되어 있다는 것을 명심해야겠다. 😅*vec.end()를 썼다가 프로그램이 비정상 종료되는 경험을 했다. 🤯 end()는 마지막 요소의 다음을 가리키므로 역참조하면 안 된다는 중요한 사실을 몸소 체험했다. 마지막 원소는 *(vec.end() - 1) 또는 vec.back()으로 접근해야 한다.map의 원소를 순회할 때, *it은 int나 string이 아니라 pair 객체라는 점을 간과했다. it->first(키)와 it->second(값)로 접근해야 하는데, *it을 바로 출력하려고 해서 애를 먹었다.| 개념 | 설명 | 비고 |
|---|---|---|
| 컨테이너 | 데이터를 저장하고 관리하는 자료구조. | vector, map, list, set 등 |
vector | 크기가 자동으로 변하는 동적 배열. 순차 데이터 관리에 용이하다. | #include <vector> |
map | Key-Value 쌍으로 데이터를 저장하며, Key를 기준으로 자동 정렬된다. | #include <map> |
| 알고리즘 | 컨테이너에 적용할 수 있는 범용 함수 (정렬, 탐색 등). | #include <algorithm> |
| 반복자 (Iterator) | 컨테이너의 원소를 가리키는 포인터 같은 객체. 컨테이너와 알고리즘을 연결한다. | begin(), end()가 핵심 |
begin() | 컨테이너의 첫 번째 원소를 가리키는 반복자. | for 루프의 시작점 |
end() | 컨테이너의 마지막 원소 다음 위치를 가리키는 반복자. | for 루프의 종료 조건 |