Menu
Coddy logo textTech

STL 컨테이너

Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 104개 중 71번째.

STL containers는 객체 컬렉션을 저장하고 구성하는 템플릿 클래스입니다. 각 컨테이너 유형은 서로 다른 access 패턴과 연산에 맞게 최적화되어 있습니다. 필요에 맞는 컨테이너를 선택하면 프로그램의 성능에 큰 영향을 줄 수 있습니다.

시퀀스 containers는 elements를 특정 순서로 유지합니다:

#include <vector>
#include <list>

std::vector<int> vec = {1, 2, 3};  // 동적 배열, 빠른 임의 접근
vec.push_back(4);                   // 끝에 추가: O(1) 분할 상환
int x = vec[2];                     // 인덱스로 접근: O(1)

std::list<int> lst = {1, 2, 3};    // 이중 연결 리스트
lst.push_front(0);                  // 앞에 추가: O(1)
lst.push_back(4);                   // 끝에 추가: O(1)

Associative containers는 정렬된 순서로 elements를 저장하여 fast 조회를 지원합니다:

#include <map>
#include <set>

std::set<int> s = {3, 1, 4, 1};    // 고유한 정렬된 요소: {1, 3, 4}
s.insert(2);                        // 삽입: O(log n)
bool found = s.count(3);            // 존재 여부 확인: O(log n)

std::map<std::string, int> ages;   // 키-값 쌍, 키로 정렬됨
ages["Alice"] = 25;                 // 삽입/업데이트: O(log n)
ages["Bob"] = 30;
std::cout << ages["Alice"];        // 접근: O(log n)

순서가 없는 컨테이너는 평균적인 경우에 더 빠른 조회를 위해 해시 테이블을 사용합니다:

#include <unordered_map>

std::unordered_map<std::string, int> scores;
scores["player1"] = 100;            // 삽입: O(1) 평균
scores["player2"] = 200;
std::cout << scores["player1"];    // 접근: O(1) 평균

빠른 임의 접근이 필요하면 vector를 사용하고, 중간에 빈번한 삽입이 필요하면 list를 사용하며, 정렬된 데이터가 필요하면 map/set을 사용하고, 조회 속도가 중요하고 순서가 중요하지 않으면 unordered_map을 사용하세요.

challenge icon

챌린지

쉬움

서로 다른 STL 컨테이너가 서로 다른 목적에 어떻게 사용되는지 보여 주는 학생 성적 관리 시스템을 만들어 보겠습니다. 여러 컨테이너 유형을 사용하여 학생 데이터를 효율적으로 정리하고, 각 작업에 적합한 컨테이너를 선택합니다.

코드를 정리하기 위해 두 개의 파일을 만듭니다.

  • GradeManager.h: 여러 STL 컨테이너를 사용하여 학생 정보를 관리하는 GradeManager 클래스를 Define합니다.

    클래스는 다음을 사용해야 합니다.

    • 추가된 순서대로 학생 이름을 저장하는 std::vector<std::string>
    • 각 학생 이름을 해당 성적과 연결하는 std::map<std::string, int>
    • 할당된 모든 고유 성적을 추적하는 std::set<int>

    다음 메서드를 Implement합니다.

    • addStudent(const std::string& name, int grade): 학생과 해당 성적을 세 컨테이너 모두에 추가합니다.
    • getGrade(const std::string& name): map을 사용하여 주어진 학생 이름의 성적을 반환합니다.
    • printRoster(): 추가된 순서대로 vector의 모든 학생 이름을 한 줄에 하나씩 출력합니다.
    • printGrades(): 모든 학생과 성적을 알파벳순으로 출력합니다(map이 이를 자동으로 처리함). 각 줄은 name: grade 형식으로 표시합니다.
    • printUniqueGrades(): 모든 고유 성적을 오름차순으로 출력합니다(set이 이를 처리함). 성적은 공백으로 구분하고 마지막에 줄 바꿈을 출력합니다.
  • main.cpp: inputs를 읽고 각 컨테이너 유형이 서로 다른 목적에 어떻게 사용되는지 보여 줍니다.

    여섯 개의 inputs를 읽습니다(each는 별도의 줄에 입력).

    1. 첫 번째 학생 이름
    2. 첫 번째 학생 성적(정수)
    3. 두 번째 학생 이름
    4. 두 번째 학생 성적(정수)
    5. 세 번째 학생 이름
    6. 세 번째 학생 성적(정수)

    GradeManager를 만들고 세 학생을 모두 추가합니다. 그런 다음 서로 다른 컨테이너 동작을 보여 줍니다.

    1. Roster (insertion order):를 출력한 후 printRoster()를 호출합니다.
    2. Grades (alphabetical):을 출력한 후 printGrades()를 호출합니다.
    3. Unique grades:을 출력한 후 printUniqueGrades()를 호출합니다.
    4. 두 번째 학생의 성적을 Look up하고 <name>'s grade: <grade>를 출력합니다.

예를 들어 inputs가 Charlie, 85, Alice, 90, Bob, 85인 경우:

Roster (insertion order):
Charlie
Alice
Bob
Grades (alphabetical):
Alice: 90
Bob: 85
Charlie: 85
Unique grades:
85 90 
Alice's grade: 90

vector는 insertion order(Charlie, Alice, Bob)를 유지하고, map은 key를 기준으로 자동 정렬하며(Alice, Bob, Charlie), set은 정렬된 order로 고유한 값만 저장한다는 점을 확인하세요(85는 두 번이 아니라 한 번만 나타남). 각 컨테이너 유형은 서로 다른 작업에 특화되어 있습니다!

직접 해보기

#include <iostream>
#include <string>
#include "GradeManager.h"

using namespace std;

int main() {
    // 세 학생의 입력을 읽기
    string name1, name2, name3;
    int grade1, grade2, grade3;
    
    cin >> name1;
    cin >> grade1;
    cin >> name2;
    cin >> grade2;
    cin >> name3;
    cin >> grade3;
    
    // TODO: GradeManager 객체 생성
    
    // TODO: 세 학생 모두를 GradeManager에 추가
    
    // TODO: Print "Roster (insertion order):" and call printRoster()
    
    // TODO: Print "Grades (alphabetical):" and call printGrades()
    
    // TODO: Print "Unique grades:" and call printUniqueGrades()
    
    // TODO: 두 번째 학생의 성적을 조회하고 "<name>'s grade: <grade>" 출력
    
    return 0;
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 C++ 컴파일러