소개
이 랩에서는 C++ 표준 템플릿 라이브러리 (STL) 의 다양한 구성 요소를 사용하여 벡터, 리스트, 맵, 세트 등과 같은 데이터 구조를 생성하고 조작하는 방법을 배우게 됩니다. 이러한 STL 컨테이너의 기본 연산, 즉 요소 추가, 제거 및 반복을 탐구할 것입니다. 또한, 이러한 컨테이너 내에서 데이터를 정렬, 검색 및 처리하기 위해 STL 알고리즘을 활용하는 방법을 배우게 됩니다. 이 랩을 마치면 효율적이고 강력한 애플리케이션을 구축하기 위해 C++ STL 의 강력함과 유연성을 활용하는 방법에 대한 확실한 이해를 갖게 될 것입니다.
벡터 컨테이너 생성 및 조작
이 단계에서는 크기가 늘어나고 줄어들 수 있는 동적 배열인 C++ 표준 템플릿 라이브러리 (STL) 벡터 컨테이너에 대해 배우게 됩니다. 벡터는 요소의 컬렉션을 저장하고 조작하는 데 매우 유용합니다.
먼저 WebIDE 를 열고 ~/project 디렉토리에 vector_demo.cpp라는 새 파일을 만듭니다. 벡터의 기본 연산을 단계별로 살펴보겠습니다.
touch ~/project/vector_demo.cpp
vector_demo.cpp 파일에 다음 코드를 추가합니다.
#include <iostream>
#include <vector>
int main() {
// Create an empty vector of integers
std::vector<int> numbers;
// Add elements to the vector using push_back()
numbers.push_back(10);
numbers.push_back(20);
numbers.push_back(30);
// Print the size of the vector
std::cout << "Vector size: " << numbers.size() << std::endl;
// Access elements using index
std::cout << "First element: " << numbers[0] << std::endl;
std::cout << "Second element: " << numbers[1] << std::endl;
// Iterate through the vector using a range-based for loop
std::cout << "All elements: ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// Remove the last element
numbers.pop_back();
// Check the new size after removing an element
std::cout << "Vector size after pop_back(): " << numbers.size() << std::endl;
return 0;
}
프로그램을 컴파일하고 실행합니다.
g++ vector_demo.cpp -o vector_demo
./vector_demo
예시 출력:
Vector size: 3
First element: 10
Second element: 20
All elements: 10 20 30
Vector size after pop_back(): 2
벡터에 대한 주요 사항:
- 벡터 라이브러리를 포함하려면
#include <vector>를 사용합니다. std::vector<type>은 특정 유형의 벡터를 생성합니다.push_back()은 벡터의 끝에 요소를 추가합니다.size()는 요소의 수를 반환합니다.- 인덱스
[]를 사용하여 요소에 접근합니다. pop_back()은 마지막 요소를 제거합니다.- 범위 기반 for 루프는 벡터를 쉽게 반복하는 방법입니다.
연결 리스트 연산을 위한 List 사용
이 단계에서는 이중 연결 리스트를 구현하는 C++ STL 리스트 컨테이너에 대해 배우게 됩니다. 리스트는 컨테이너의 모든 위치에서 효율적인 삽입 및 삭제 연산을 제공합니다.
WebIDE 를 열고 ~/project 디렉토리에 list_demo.cpp라는 새 파일을 만듭니다.
touch ~/project/list_demo.cpp
list_demo.cpp 파일에 다음 코드를 추가합니다.
#include <iostream>
#include <list>
int main() {
// Create an empty list of integers
std::list<int> numbers;
// Add elements to the list
numbers.push_back(10); // Add to the end
numbers.push_front(5); // Add to the beginning
numbers.push_back(20);
// Print the list size
std::cout << "List size: " << numbers.size() << std::endl;
// Iterate through the list
std::cout << "List elements: ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// Remove elements
numbers.pop_front(); // Remove first element
numbers.pop_back(); // Remove last element
// Insert an element at a specific position
auto it = numbers.begin();
numbers.insert(it, 15);
// Print updated list
std::cout << "Updated list: ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// Check if list is empty
std::cout << "Is list empty? "
<< (numbers.empty() ? "Yes" : "No") << std::endl;
return 0;
}
프로그램을 컴파일하고 실행합니다.
g++ list_demo.cpp -o list_demo
./list_demo
예시 출력:
List size: 3
List elements: 5 10 20
Updated list: 15 10
Is list empty? No
리스트에 대한 주요 사항:
- 리스트 라이브러리를 포함하려면
#include <list>를 사용합니다. push_back()은 끝에 요소를 추가합니다.push_front()는 시작 부분에 요소를 추가합니다.pop_front()및pop_back()은 요소를 제거합니다.insert()는 특정 위치에 요소를 추가할 수 있습니다.begin()은 첫 번째 요소에 대한 반복자 (iterator) 를 반환합니다.empty()는 리스트가 비어 있는지 확인합니다.
Map 을 이용한 키 - 값 쌍 구현
이 단계에서는 정렬되고 고유한 키 순서로 키 - 값 쌍을 저장하는 C++ STL map 컨테이너에 대해 배우게 됩니다. Map 은 사전 또는 연관 배열을 만드는 데 유용합니다.
WebIDE 를 열고 ~/project 디렉토리에 map_demo.cpp라는 새 파일을 만듭니다.
touch ~/project/map_demo.cpp
map_demo.cpp 파일에 다음 코드를 추가합니다.
#include <iostream>
#include <map>
#include <string>
int main() {
// Create a map to store student names and their ages
std::map<std::string, int> students;
// Insert key-value pairs
students["Alice"] = 20;
students["Bob"] = 22;
students["Charlie"] = 21;
// Access values using keys
std::cout << "Alice's age: " << students["Alice"] << std::endl;
// Check if a key exists
if (students.count("David") == 0) {
std::cout << "David is not in the map" << std::endl;
}
// Iterate through the map
std::cout << "All students:" << std::endl;
for (const auto& student : students) {
std::cout << student.first << ": " << student.second << std::endl;
}
// Remove a key-value pair
students.erase("Bob");
// Check the size of the map
std::cout << "Number of students: " << students.size() << std::endl;
return 0;
}
프로그램을 컴파일하고 실행합니다.
g++ map_demo.cpp -o map_demo
./map_demo
예시 출력:
Alice's age: 20
David is not in the map
All students:
Alice: 20
Bob: 22
Charlie: 21
Number of students: 2
Map 에 대한 주요 사항:
map라이브러리를 포함하려면#include <map>을 사용합니다.map<KeyType, ValueType>는 지정된 키 및 값 유형으로 map 을 생성합니다.- 대괄호
[]를 사용하여 값에 접근합니다. count()는 키가 존재하는지 확인합니다.- 범위 기반 for 루프를 사용하여 map 을 반복합니다.
erase()는 키 - 값 쌍을 제거합니다.size()는 요소의 수를 반환합니다.
Set 을 사용하여 고유 요소 저장
이 단계에서는 정렬된 순서로 고유 요소를 저장하는 C++ STL set 컨테이너에 대해 배우게 됩니다. Set 은 자동으로 중복 값을 방지하고 특정 순서로 요소를 유지합니다.
WebIDE 를 열고 ~/project 디렉토리에 set_demo.cpp라는 새 파일을 만듭니다.
touch ~/project/set_demo.cpp
set_demo.cpp 파일에 다음 코드를 추가합니다.
#include <iostream>
#include <set>
int main() {
// Create a set of integers
std::set<int> numbers;
// Insert elements
numbers.insert(10);
numbers.insert(20);
numbers.insert(30);
numbers.insert(10); // Duplicate, will not be added
// Print the size of the set
std::cout << "Set size: " << numbers.size() << std::endl;
// Iterate through the set
std::cout << "Set elements: ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// Check if an element exists
if (numbers.count(20) > 0) {
std::cout << "20 is in the set" << std::endl;
}
// Remove an element
numbers.erase(20);
// Check the size after removal
std::cout << "Set size after removal: " << numbers.size() << std::endl;
// Clear the set
numbers.clear();
// Check if the set is empty
std::cout << "Is set empty? "
<< (numbers.empty() ? "Yes" : "No") << std::endl;
return 0;
}
프로그램을 컴파일하고 실행합니다.
g++ set_demo.cpp -o set_demo
./set_demo
예시 출력:
Set size: 3
Set elements: 10 20 30
20 is in the set
Set size after removal: 2
Is set empty? Yes
Set 에 대한 주요 사항:
set라이브러리를 포함하려면#include <set>을 사용합니다.set<type>은 고유 요소의 set 을 생성합니다.insert()는 요소를 추가합니다 (중복은 무시됨).count()는 요소의 존재 여부를 확인합니다.erase()는 요소를 제거합니다.clear()는 모든 요소를 제거합니다.empty()는 set 이 비어 있는지 확인합니다.- 요소는 자동으로 정렬됩니다.
STL sort 알고리즘으로 요소 정렬
이 단계에서는 STL sort 알고리즘을 사용하여 요소를 오름차순 또는 내림차순으로 정렬하는 방법을 배우게 됩니다. <algorithm> 라이브러리는 다양한 컨테이너에 대한 강력한 정렬 기능을 제공합니다.
WebIDE 를 열고 ~/project 디렉토리에 sort_demo.cpp라는 새 파일을 만듭니다.
touch ~/project/sort_demo.cpp
sort_demo.cpp 파일에 다음 코드를 추가합니다.
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
// Create a vector of integers
std::vector<int> numbers = {5, 2, 8, 1, 9, 3};
// Print original vector
std::cout << "Original vector: ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// Sort the vector in ascending order
std::sort(numbers.begin(), numbers.end());
// Print sorted vector
std::cout << "Sorted vector (ascending): ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// Sort the vector in descending order
std::sort(numbers.begin(), numbers.end(), std::greater<int>());
// Print vector sorted in descending order
std::cout << "Sorted vector (descending): ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
프로그램을 컴파일하고 실행합니다.
g++ sort_demo.cpp -o sort_demo
./sort_demo
예시 출력:
Original vector: 5 2 8 1 9 3
Sorted vector (ascending): 1 2 3 5 8 9
Sorted vector (descending): 9 8 5 3 2 1
STL sort 에 대한 주요 사항:
- 정렬을 위해
<algorithm>라이브러리를 포함합니다. std::sort()는 다양한 컨테이너에서 작동합니다.- 기본 정렬은 오름차순입니다.
std::greater<type>()은 내림차순으로 정렬합니다.- 정렬은 제자리에서 수행되어 원래 컨테이너를 수정합니다.
- 다양한 컨테이너 유형에서 효율적으로 작동합니다.
STL 알고리즘을 사용하여 요소 찾기
이 단계에서는 STL 알고리즘을 사용하여 컨테이너에서 요소를 찾고 검색하는 방법을 배우게 됩니다. <algorithm> 라이브러리는 요소를 검색하고 찾는 강력한 기능을 제공합니다.
WebIDE 를 열고 ~/project 디렉토리에 find_demo.cpp라는 새 파일을 만듭니다.
touch ~/project/find_demo.cpp
find_demo.cpp 파일에 다음 코드를 추가합니다.
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
// Create a vector of integers
std::vector<int> numbers = {5, 2, 8, 1, 9, 3, 8};
// Find first occurrence of a specific element
auto it = std::find(numbers.begin(), numbers.end(), 8);
if (it != numbers.end()) {
std::cout << "First occurrence of 8 at index: "
<< std::distance(numbers.begin(), it) << std::endl;
}
// Count occurrences of an element
int count = std::count(numbers.begin(), numbers.end(), 8);
std::cout << "Number of 8s in the vector: " << count << std::endl;
// Find if any element is greater than 6
bool has_large_element = std::any_of(numbers.begin(), numbers.end(),
[](int n) { return n > 6; });
std::cout << "Vector has element > 6: "
<< (has_large_element ? "Yes" : "No") << std::endl;
// Find the minimum and maximum elements
auto min_it = std::min_element(numbers.begin(), numbers.end());
auto max_it = std::max_element(numbers.begin(), numbers.end());
std::cout << "Minimum element: " << *min_it << std::endl;
std::cout << "Maximum element: " << *max_it << std::endl;
return 0;
}
프로그램을 컴파일하고 실행합니다.
g++ find_demo.cpp -o find_demo
./find_demo
예시 출력:
First occurrence of 8 at index: 2
Number of 8s in the vector: 2
Vector has element > 6: Yes
Minimum element: 1
Maximum element: 9
STL 검색 알고리즘에 대한 주요 사항:
std::find()는 요소의 첫 번째 발생 위치를 찾습니다.std::count()는 요소의 발생 횟수를 계산합니다.std::any_of()는 요소가 조건을 충족하는지 확인합니다.std::min_element()및std::max_element()는 극값 (최소값 및 최대값) 을 찾습니다.- 람다 함수를 사용하여 사용자 정의 검색 조건을 사용할 수 있습니다.
- 반환된 반복자는 찾은 요소를 가리킵니다.
컨테이너 순회하기
이 단계에서는 다양한 반복 기술을 사용하여 STL 컨테이너를 반복하는 여러 가지 방법을 배우게 됩니다. 범위 기반 for 루프, 반복자 (iterator), 전통적인 인덱스 기반 반복을 살펴보겠습니다.
WebIDE 를 열고 ~/project 디렉토리에 iteration_demo.cpp라는 새 파일을 만듭니다.
touch ~/project/iteration_demo.cpp
iteration_demo.cpp 파일에 다음 코드를 추가합니다.
#include <iostream>
#include <vector>
#include <list>
#include <map>
int main() {
// Vector iteration
std::vector<int> numbers = {10, 20, 30, 40, 50};
// Method 1: Range-based for loop (most modern and readable)
std::cout << "Vector iteration (range-based for):" << std::endl;
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// Method 2: Iterator-based iteration
std::cout << "Vector iteration (iterators):" << std::endl;
for (auto it = numbers.begin(); it != numbers.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// Method 3: Index-based iteration
std::cout << "Vector iteration (index-based):" << std::endl;
for (size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers[i] << " ";
}
std::cout << std::endl;
// Map iteration
std::map<std::string, int> ages = {
{"Alice", 25},
{"Bob", 30},
{"Charlie", 35}
};
std::cout << "Map iteration:" << std::endl;
for (const auto& pair : ages) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
프로그램을 컴파일하고 실행합니다.
g++ iteration_demo.cpp -o iteration_demo
./iteration_demo
예시 출력:
Vector iteration (range-based for):
10 20 30 40 50
Vector iteration (iterators):
10 20 30 40 50
Vector iteration (index-based):
10 20 30 40 50
Map iteration:
Alice: 25
Bob: 30
Charlie: 35
컨테이너 반복에 대한 주요 사항:
- 범위 기반 for 루프가 가장 현대적이고 읽기 쉽습니다.
- 반복자는 컨테이너 순회에 대한 세밀한 제어를 제공합니다.
- 인덱스 기반 반복은 임의 접근 컨테이너에서 잘 작동합니다.
auto키워드는 형식 추론에 도움이 됩니다.- 서로 다른 컨테이너는 서로 다른 반복 방법을 지원합니다.
STL Stack 및 Queue 사용
이 단계에서는 두 가지 중요한 STL 컨테이너 어댑터인 스택 (stack) 과 큐 (queue) 에 대해 배우게 됩니다. 이러한 컨테이너는 LIFO(Last-In-First-Out, 후입선출) 및 FIFO(First-In-First-Out, 선입선출) 데이터 관리를 위한 특수 연산을 제공합니다.
WebIDE 를 열고 ~/project 디렉토리에 stack_queue_demo.cpp라는 새 파일을 만듭니다.
touch ~/project/stack_queue_demo.cpp
stack_queue_demo.cpp 파일에 다음 코드를 추가합니다.
#include <iostream>
#include <stack>
#include <queue>
int main() {
// Stack demonstration
std::stack<int> myStack;
// Push elements onto the stack
myStack.push(10);
myStack.push(20);
myStack.push(30);
std::cout << "Stack operations:" << std::endl;
std::cout << "Top element: " << myStack.top() << std::endl;
// Remove top element
myStack.pop();
std::cout << "Top element after pop: " << myStack.top() << std::endl;
std::cout << "Stack size: " << myStack.size() << std::endl;
// Queue demonstration
std::queue<std::string> myQueue;
// Add elements to the queue
myQueue.push("Alice");
myQueue.push("Bob");
myQueue.push("Charlie");
std::cout << "\nQueue operations:" << std::endl;
std::cout << "Front element: " << myQueue.front() << std::endl;
std::cout << "Back element: " << myQueue.back() << std::endl;
// Remove front element
myQueue.pop();
std::cout << "Front element after pop: " << myQueue.front() << std::endl;
std::cout << "Queue size: " << myQueue.size() << std::endl;
return 0;
}
프로그램을 컴파일하고 실행합니다.
g++ stack_queue_demo.cpp -o stack_queue_demo
./stack_queue_demo
예시 출력:
Stack operations:
Top element: 30
Top element after pop: 20
Stack size: 2
Queue operations:
Front element: Alice
Back element: Charlie
Front element after pop: Bob
Queue size: 2
스택과 큐에 대한 주요 사항:
- 스택 (LIFO - Last In, First Out)
push()는 요소를 맨 위에 추가합니다.pop()은 맨 위 요소를 제거합니다.top()은 맨 위 요소를 반환합니다.
- 큐 (FIFO - First In, First Out)
push()는 요소를 뒤에 추가합니다.pop()은 앞쪽 요소를 제거합니다.front()는 첫 번째 요소를 반환합니다.back()은 마지막 요소를 반환합니다.
- 둘 다 요소 수를 확인하는
size()메서드를 가지고 있습니다. <stack>및<queue>헤더를 포함합니다.
컨테이너 예외 안전성 처리
이 단계에서는 예외를 처리하고 STL 컨테이너로 안전한 작업을 수행하는 방법을 배우게 됩니다. 예외 처리는 프로그램 충돌을 방지하고 강력한 오류 관리를 제공합니다.
WebIDE 를 열고 ~/project 디렉토리에 exception_safety_demo.cpp라는 새 파일을 만듭니다.
touch ~/project/exception_safety_demo.cpp
exception_safety_demo.cpp 파일에 다음 코드를 추가합니다.
#include <iostream>
#include <vector>
#include <stdexcept>
void demonstrateVectorSafety() {
std::vector<int> numbers;
try {
// Attempt to access an element from an empty vector
std::cout << "Attempting to access element from empty vector:" << std::endl;
numbers.at(0); // This will throw an out_of_range exception
}
catch (const std::out_of_range& e) {
std::cout << "Out of Range Error: " << e.what() << std::endl;
}
// Safe element addition
try {
numbers.push_back(10);
numbers.push_back(20);
std::cout << "Vector size: " << numbers.size() << std::endl;
// Safe element access
std::cout << "First element: " << numbers.at(0) << std::endl;
std::cout << "Second element: " << numbers.at(1) << std::endl;
}
catch (const std::exception& e) {
std::cout << "An error occurred: " << e.what() << std::endl;
}
}
int main() {
// Demonstrate vector exception safety
demonstrateVectorSafety();
return 0;
}
프로그램을 컴파일하고 실행합니다.
g++ exception_safety_demo.cpp -o exception_safety_demo
./exception_safety_demo
예시 출력:
Attempting to access element from empty vector:
Out of Range Error: vector
Vector size: 2
First element: 10
Second element: 20
컨테이너 예외 안전성에 대한 주요 사항:
- 잠재적인 예외를 처리하려면
try-catch블록을 사용합니다. - 잘못된 벡터 요소에 접근할 때
std::out_of_range가 발생합니다. at()메서드는[]연산자와 달리 경계 검사를 수행합니다.- 먼저 특정 예외를 잡고, 그 다음 더 일반적인 예외를 잡습니다.
- 프로그램 충돌을 방지하려면 항상 잠재적인 예외를 처리합니다.
<stdexcept>에서 표준 예외 클래스를 사용합니다.
요약
이 랩에서는 C++ 표준 템플릿 라이브러리 (STL) 의 다양한 구성 요소와 이를 효과적으로 사용하는 방법에 대해 배웠습니다. 먼저 크기가 늘어나고 줄어들 수 있는 동적 배열인 벡터 (vector) 컨테이너를 살펴보았습니다. 요소를 추가하고 제거하고, 인덱스를 사용하여 액세스하고, 범위 기반 for 루프를 사용하여 벡터를 반복하는 방법을 배웠습니다.
다음으로, 이중 연결 리스트 구현인 리스트 (list) 컨테이너를 자세히 살펴보았습니다. 요소를 삽입, 삭제 및 순회하는 것과 같은 일반적인 연결 리스트 연산을 수행하는 방법을 배웠습니다. 또한 키 - 값 쌍을 저장할 수 있는 맵 (map) 컨테이너와 고유한 요소를 저장하는 세트 (set) 컨테이너를 살펴보았습니다. 또한, 이러한 컨테이너 내에서 요소를 조작하고 검색하기 위해 sort 및 find 와 같은 STL 알고리즘을 사용하는 방법을 배웠습니다. 마지막으로, 스택 (stack) 및 큐 (queue) 컨테이너를 살펴보고 STL 구성 요소로 작업할 때 예외 안전성의 중요성에 대해 논의했습니다.



