[DAY14] STL Basics: Efficient Code with Containers, Algorithms, and Iterators

베리투스·2025년 8월 22일

TIL: Today I Learned

목록 보기
22/93

C++의 강력한 표준 템플릿 라이브러리인 STL(Standard Template Library)의 기초를 학습했다. 데이터를 효율적으로 관리하는 컨테이너(주로 vectormap), 데이터를 처리하는 알고리즘(sort, find), 그리고 이 둘을 연결하는 반복자의 세 가지 핵심 구성 요소를 배웠다. 🚀 STL을 활용하면 복잡한 자료구조나 알고리즘을 직접 구현할 필요 없이, 생산성 높고 안정적인 코드를 작성할 수 있다는 점을 깨달았다.


📌 목표

  • STL의 세 가지 핵심 구성 요소(컨테이너, 알고리즘, 반복자) 이해
  • vectormap 컨테이너의 선언 및 기본 사용법 익히기
  • sort, find 알고리즘을 활용하여 데이터를 처리하기
  • 반복자를 이용해 컨테이너의 원소를 안전하게 순회하기

📖 이론

1. STL (Standard Template Library) 이란?

  • C++ 표준 라이브러리의 일부로, 자주 사용되는 자료구조와 알고리즘을 템플릿 기반으로 제공하는 라이브러리다.
  • 템플릿으로 만들어져 있어 int, string, 사용자 정의 class 등 어떤 타입의 데이터든 담고 처리할 수 있다.
  • 핵심 구성 요소는 컨테이너, 알고리즘, 반복자 세 가지다.

2. 컨테이너 (Container)

  • 데이터를 저장하고 관리하는 자료구조 객체다. (e.g., 동적 배열, 키-값 쌍 등)
  • 주요 특징:
    1. 템플릿 기반으로 다양한 타입의 데이터를 저장할 수 있다.
    2. 메모리 관리를 내부적으로 자동 처리해준다.
    3. 반복자를 제공하여 원소들을 순회할 수 있는 표준화된 방법을 제공한다.
  • vector: 배열처럼 순차적인 데이터를 저장하는 동적 배열 컨테이너. 크기가 자동으로 조절된다.
  • map: KeyValue를 하나의 쌍으로 저장하는 연관 컨테이너. Key를 기준으로 자동 정렬되며, Key는 중복될 수 없다.

3. 알고리즘 (Algorithm)

  • 컨테이너의 원소에 대해 정렬, 탐색, 수정 등의 작업을 수행하는 함수다.
  • 특정 컨테이너에 종속되지 않고, 반복자를 통해 모든 종류의 컨테이너에 범용적으로 적용할 수 있다.
  • sort: 지정된 범위의 원소를 정렬한다. (기본은 오름차순)
  • find: 지정된 범위에서 특정 값을 찾아 그 위치의 반복자를 반환한다.

4. 반복자 (Iterator)

  • 컨테이너의 원소를 가리키는 포인터와 유사한 객체다.
  • 컨테이너의 내부 구조를 몰라도 ++(다음 원소로 이동), *(역참조하여 값 접근) 등의 연산을 통해 원소를 순회하고 접근할 수 있게 해준다.
  • 컨테이너와 알고리즘을 연결하는 다리 역할을 한다. 알고리즘은 반복자를 통해 컨테이너의 종류와 상관없이 동일한 방식으로 동작할 수 있다.
  • begin(): 컨테이너의 첫 번째 원소를 가리키는 반복자를 반환한다.
  • end(): 컨테이너의 마지막 원소 바로 다음을 가리키는 반복자를 반환한다.
  • rbegin(), rend(): 역순 순회를 위한 반복자다. (reverse begin, reverse end)

💻 코드

STL 기본 활용 예제 (vector, map, algorithm)

#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;
}

⚠️ 실수

  • sortfind 같은 알고리즘 함수를 사용하면서 #include <algorithm> 헤더를 추가하는 것을 잊어 컴파일 에러를 만났다. STL의 기능들은 각기 다른 헤더 파일에 정의되어 있다는 것을 명심해야겠다. 😅
  • 벡터의 마지막 원소를 출력하려고 무심코 *vec.end()를 썼다가 프로그램이 비정상 종료되는 경험을 했다. 🤯 end()는 마지막 요소의 다음을 가리키므로 역참조하면 안 된다는 중요한 사실을 몸소 체험했다. 마지막 원소는 *(vec.end() - 1) 또는 vec.back()으로 접근해야 한다.
  • map의 원소를 순회할 때, *itintstring이 아니라 pair 객체라는 점을 간과했다. it->first(키)와 it->second(값)로 접근해야 하는데, *it을 바로 출력하려고 해서 애를 먹었다.

✅ 핵심 요약

개념설명비고
컨테이너데이터를 저장하고 관리하는 자료구조.vector, map, list, set
vector크기가 자동으로 변하는 동적 배열. 순차 데이터 관리에 용이하다.#include <vector>
mapKey-Value 쌍으로 데이터를 저장하며, Key를 기준으로 자동 정렬된다.#include <map>
알고리즘컨테이너에 적용할 수 있는 범용 함수 (정렬, 탐색 등).#include <algorithm>
반복자 (Iterator)컨테이너의 원소를 가리키는 포인터 같은 객체. 컨테이너와 알고리즘을 연결한다.begin(), end()가 핵심
begin()컨테이너의 첫 번째 원소를 가리키는 반복자.for 루프의 시작점
end()컨테이너의 마지막 원소 다음 위치를 가리키는 반복자.for 루프의 종료 조건
profile
Shin Ji Yong // Unreal Engine 5 공부중입니다~

0개의 댓글