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을 사용하세요.
챌린지
쉬움서로 다른 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는 별도의 줄에 입력).
- 첫 번째 학생 이름
- 첫 번째 학생 성적(정수)
- 두 번째 학생 이름
- 두 번째 학생 성적(정수)
- 세 번째 학생 이름
- 세 번째 학생 성적(정수)
GradeManager를 만들고 세 학생을 모두 추가합니다. 그런 다음 서로 다른 컨테이너 동작을 보여 줍니다.Roster (insertion order):를 출력한 후printRoster()를 호출합니다.Grades (alphabetical):을 출력한 후printGrades()를 호출합니다.Unique grades:을 출력한 후printUniqueGrades()를 호출합니다.- 두 번째 학생의 성적을 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: 90vector는 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;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 C++ 컴파일러