반복자
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 104개 중 72번째.
반복자(Iterators)는 컨테이너와 알고리즘 사이의 가교 역할을 하는 객체입니다. 반복자는 컨테이너가 내부적으로 데이터를 어떻게 저장하는지에 관계없이, 모든 컨테이너의 요소에 접근할 수 있는 일관된 방식을 제공합니다. 반복자를 컨테이너를 순회하는 방법을 알고 있는 일반화된 포인터라고 생각하면 됩니다.
모든 STL 컨테이너는 begin()과 end() 메서드를 제공합니다. begin() 반복자는 첫 번째 요소를 가리키는 반면, end()는 마지막 요소의 다음 위치를 가리킵니다. 이는 어디서 멈춰야 할지를 표시하는 센티널(sentinel)입니다:
#include <vector>
#include <iostream>
int main() {
std::vector<int> nums = {10, 20, 30};
for (std::vector<int>::iterator it = nums.begin(); it != nums.end(); ++it) {
std::cout << *it << " "; // 값을 얻기 위해 역참조
}
// 출력: 10 20 30
}auto 키워드는 반복자(iterator) 선언을 상당히 단순화합니다:
for (auto it = nums.begin(); it != nums.end(); ++it) {
*it *= 2; // 반복자를 통해 요소 수정
}
// nums는 이제 {20, 40, 60}입니다반복자는 기능에 따라 여러 범주로 나뉩니다. 임의 접근 반복자(vector에서 제공하는 것과 같은)는 it + 3 또는 it1 - it2와 같은 산술 연산을 지원합니다.
양방향 반복자(list, map에서 제공)는 ++와 --를 사용하여 앞뒤로 이동할 수 있습니다. 순방향 반복자는 한 방향으로만 이동할 수 있습니다.
역방향 순회를 하려면 rbegin() 및 rend()를 사용하세요:
for (auto rit = nums.rbegin(); rit != nums.rend(); ++rit) {
std::cout << *rit << " "; // 역순으로 출력합니다
}챌린지
쉬움반복자(iterator)를 사용하여 아이템 컬렉션을 순회하고 조작하는 인벤토리 추적 시스템을 구축해 보겠습니다. 다양한 반복자 유형을 사용하여 여러 방식으로 데이터를 탐색하는 연습을 하게 됩니다.
코드는 두 개의 파일로 구성됩니다:
Inventory.h:std::vector<int>에 저장된 아이템 수량 컬렉션을 관리하는Inventory클래스를 정의합니다.클래스는 다음 메서드들을 제공해야 합니다:
addItem(int quantity)— 인벤토리에 아이템 수량을 추가합니다.printForward()—begin()및end()와 함께 반복자를 사용하여 모든 수량을 공백으로 구분하여 출력하고, 마지막에 줄바꿈을 추가합니다.printReverse()—rbegin()및rend()와 함께 역반복자(reverse iterator)를 사용하여 모든 수량을 역순으로 공백으로 구분하여 출력하고, 마지막에 줄바꿈을 추가합니다.doubleAll()— 반복자를 사용하여 벡터를 순회하며 각 수량을 그 자리에서 두 배로 만듭니다.getTotal()— 반복자를 사용하여 모든 수량의 합계를 계산하고 반환합니다.
코드를 깔끔하게 유지하기 위해 반복자 선언 시
auto키워드를 사용하세요.main.cpp: 아이템 수량을 나타내는 네 개의 정수 입력(각각 별도의 줄)을 읽습니다.Inventory객체를 생성하고 네 개의 수량을 모두 추가합니다. 그런 다음 아래 순서대로 반복자 사용법을 시연합니다:Forward:를 출력한 후printForward()를 호출합니다.Reverse:를 출력한 후printReverse()를 호출합니다.getTotal()을 사용하여Total: <sum>을 출력합니다.doubleAll()을 호출하여 수량을 수정합니다.After doubling:을 출력한 후printForward()를 호출합니다.getTotal()을 사용하여New total: <sum>을 출력합니다.
예를 들어, 입력값이 10, 25, 15, 30인 경우의 출력은 다음과 같습니다:
Forward: 10 25 15 30
Reverse: 30 15 25 10
Total: 80
After doubling: 20 50 30 60
New total: 160이 챌린지를 통해 반복자를 사용하여 요소를 읽는 방법(출력 및 합계 계산)과 반복자를 통해 요소를 수정하는 방법(두 배로 만들기)을 모두 연습할 수 있습니다. 또한 역반복자를 사용하면 인덱스 조작 없이도 역방향 순회가 얼마나 간편해지는지 확인할 수 있습니다.
치트 시트
반복자(Iterator)는 컨테이너의 요소에 접근하는 통일된 방법을 제공하는 객체입니다. 이들은 컨테이너를 탐색하는 방법을 알고 있는 일반화된 포인터처럼 동작합니다.
모든 STL 컨테이너는 begin()과 end() 메서드를 제공합니다. begin() 반복자는 첫 번째 요소를 가리키고, end()는 마지막 요소의 다음 위치를 가리킵니다:
std::vector<int> nums = {10, 20, 30};
for (std::vector<int>::iterator it = nums.begin(); it != nums.end(); ++it) {
std::cout << *it << " "; // 역참조하여 값을 가져옴
}auto 키워드를 사용하여 반복자 선언을 간소화하세요:
for (auto it = nums.begin(); it != nums.end(); ++it) {
*it *= 2; // 반복자를 통해 요소 수정
}기능에 따른 반복자 분류:
- 임의 접근 반복자 (예:
vector)는it + 3또는it1 - it2와 같은 산술 연산을 지원합니다. - 양방향 반복자 (예:
list,map)는++와--를 사용하여 앞뒤로 이동할 수 있습니다. - 순방향 반복자는 한 방향으로만 이동할 수 있습니다.
역방향 순회를 위해서는 rbegin()과 rend()를 사용하세요:
for (auto rit = nums.rbegin(); rit != nums.rend(); ++rit) {
std::cout << *rit << " "; // 역순으로 출력
}직접 해보기
#include <iostream>
#include "Inventory.h"
using namespace std;
int main() {
// 네 개의 정수 입력 읽기
int q1, q2, q3, q4;
cin >> q1;
cin >> q2;
cin >> q3;
cin >> q4;
// TODO: Inventory 객체 생성
// TODO: 인벤토리에 네 개의 수량 모두 추가
// TODO: "Forward: "를 출력한 후 printForward() 호출
// TODO: "Reverse: "를 출력한 후 printReverse() 호출
// TODO: "Total: "을 출력한 후 getTotal()의 결과 출력
// TODO: 수량을 수정하기 위해 doubleAll() 호출
// TODO: "After doubling: "을 출력한 후 printForward() 호출
// TODO: "New total: "을 출력한 후 getTotal()의 결과 출력
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.