icon안동민 개발노트

컨테이너 개요 (vector, list, map 등)


STL 컨테이너의 개념

 STL(Standard Template Library) 컨테이너는 C++에서 제공하는 재사용 가능한 데이터 구조입니다. 이들은 다양한 타입의 객체를 저장하고 관리하는 데 사용됩니다.

 주요 특징

  1. 템플릿 기반 : 다양한 데이터 타입을 저장할 수 있습니다.
  2. 메모리 관리 자동화 : 동적 할당과 해제를 자동으로 처리합니다.
  3. 알고리즘과의 호환성 : STL 알고리즘과 함께 사용할 수 있습니다.
  4. 일관된 인터페이스 : 대부분의 컨테이너가 유사한 멤버 함수를 제공합니다.

컨테이너의 분류

 STL 컨테이너는 크게 세 가지 범주로 나눌 수 있습니다.

  1. 시퀀스 컨테이너 : 선형적으로 요소를 저장
  • vector, list, deque
  1. 연관 컨테이너 : 키를 기반으로 요소를 저장
  • set, multiset, map, multimap
  1. 컨테이너 어댑터 : 다른 컨테이너를 기반으로 특정 인터페이스를 제공
  • stack, queue, priority_queue

주요 컨테이너 소개

 vector

 vector는 동적 배열을 구현한 컨테이너입니다.

 특징

  • 연속된 메모리 공간에 요소 저장
  • 빠른 임의 접근 (O(1))
  • 끝에서의 삽입/삭제 효율적 (O(1) 평균)
  • 중간에서의 삽입/삭제는 비효율적 (O(n))
예제
// 예제
#include <iostream>
#include <vector>
 
int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    
    vec.push_back(6);  // 끝에 요소 추가
    vec[0] = 10;       // 첫 번째 요소 수정
 
    for (int num : vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
 
    return 0;
}

 list

 list는 이중 연결 리스트를 구현한 컨테이너입니다.

 특징

  • 비연속적인 메모리 공간에 요소 저장
  • 양방향 반복자 제공
  • 어느 위치에서든 삽입/삭제 효율적 (O(1))
예제
// 예제
#include <iostream>
#include <list>
 
int main() {
    std::list<int> lst = {1, 2, 3, 4, 5};
    
    lst.push_front(0);  // 앞에 요소 추가
    lst.push_back(6);   // 뒤에 요소 추가
 
    for (int num : lst) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
 
    return 0;
}

 map

 map은 키-값 쌍을 저장하는 연관 컨테이너입니다.

 특징

  • 키를 기준으로 정렬된 상태 유지
  • 빠른 검색 (O(log n))
  • 유일한 키 보장
예제
// 예제
#include <iostream>
#include <map>
#include <string>
 
int main() {
    std::map<std::string, int> ages;
    
    ages["Alice"] = 30;
    ages["Bob"] = 25;
    ages["Charlie"] = 35;
 
    for (const auto& pair : ages) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }
 
    return 0;
}

컨테이너 선택 기준

 적절한 컨테이너 선택은 다음 요소들을 고려해야 합니다.

  1. 데이터 접근 패턴 (순차적 vs 임의)
  2. 삽입/삭제 빈도 및 위치
  3. 메모리 사용량
  4. 성능 요구사항

 예를 들어,

  • 빈번한 임의 접근이 필요하다면 vector
  • 빈번한 중간 삽입/삭제가 필요하다면 list
  • 키-값 쌍으로 데이터를 관리해야 한다면 map

실습 : 다양한 컨테이너 활용

 다음 요구사항을 만족하는 프로그램을 작성해보세요.

  1. vector를 사용하여 학생들의 점수를 저장하고 평균을 계산
  2. list를 사용하여 할 일 목록을 관리 (추가, 완료 표시, 삭제)
  3. map을 사용하여 학생 이름과 성적을 연결하여 저장
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <string>
#include <numeric>
 
// 1. vector를 사용한 점수 관리
void manageScores() {
    std::vector<int> scores = {85, 92, 78, 90, 88};
    double average = std::accumulate(scores.begin(), scores.end(), 0.0) / scores.size();
    std::cout << "Average score: " << average << std::endl;
}
 
// 2. list를 사용한 할 일 목록 관리
void manageTodoList() {
    std::list<std::string> todos;
    todos.push_back("Buy groceries");
    todos.push_back("Finish homework");
    todos.push_back("Call mom");
 
    // 완료된 항목 삭제
    todos.remove("Buy groceries");
 
    std::cout << "Todo List:" << std::endl;
    for (const auto& todo : todos) {
        std::cout << "- " << todo << std::endl;
    }
}
 
// 3. map을 사용한 학생 성적 관리
void manageStudentGrades() {
    std::map<std::string, char> grades;
    grades["Alice"] = 'A';
    grades["Bob"] = 'B';
    grades["Charlie"] = 'A';
 
    std::cout << "Student Grades:" << std::endl;
    for (const auto& [name, grade] : grades) {
        std::cout << name << ": " << grade << std::endl;
    }
}
 
int main() {
    manageScores();
    std::cout << std::endl;
    manageTodoList();
    std::cout << std::endl;
    manageStudentGrades();
    return 0;
}

연습 문제

  1. vector를 사용하여 정수 배열을 저장하고, 짝수만 필터링하여 새로운 vector를 만드는 함수를 작성하세요.
  2. list를 사용하여 문자열을 저장하고, 사용자로부터 입력받은 문자열을 알파벳 순서에 맞게 삽입하는 프로그램을 작성하세요.
  3. map을 사용하여 단어와 그 빈도수를 저장하는 간단한 단어 카운터 프로그램을 작성하세요.


참고 자료

  • "The C++ Standard Library" by Nicolai M. Josuttis
  • C++ Reference : Containers library
  • "Effective STL" by Scott Meyers