Menu
Coddy logo textTech

반복자

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 << " ";  // 역순으로 출력합니다
}
challenge icon

챌린지

쉬움

반복자(iterator)를 사용하여 아이템 컬렉션을 순회하고 조작하는 인벤토리 추적 시스템을 구축해 보겠습니다. 다양한 반복자 유형을 사용하여 여러 방식으로 데이터를 탐색하는 연습을 하게 됩니다.

코드는 두 개의 파일로 구성됩니다:

  • Inventory.h: std::vector<int>에 저장된 아이템 수량 컬렉션을 관리하는 Inventory 클래스를 정의합니다.

    클래스는 다음 메서드들을 제공해야 합니다:

    • addItem(int quantity) — 인벤토리에 아이템 수량을 추가합니다.
    • printForward()begin()end()와 함께 반복자를 사용하여 모든 수량을 공백으로 구분하여 출력하고, 마지막에 줄바꿈을 추가합니다.
    • printReverse()rbegin()rend()와 함께 역반복자(reverse iterator)를 사용하여 모든 수량을 역순으로 공백으로 구분하여 출력하고, 마지막에 줄바꿈을 추가합니다.
    • doubleAll() — 반복자를 사용하여 벡터를 순회하며 각 수량을 그 자리에서 두 배로 만듭니다.
    • getTotal() — 반복자를 사용하여 모든 수량의 합계를 계산하고 반환합니다.

    코드를 깔끔하게 유지하기 위해 반복자 선언 시 auto 키워드를 사용하세요.

  • main.cpp: 아이템 수량을 나타내는 네 개의 정수 입력(각각 별도의 줄)을 읽습니다.

    Inventory 객체를 생성하고 네 개의 수량을 모두 추가합니다. 그런 다음 아래 순서대로 반복자 사용법을 시연합니다:

    1. Forward:를 출력한 후 printForward()를 호출합니다.
    2. Reverse:를 출력한 후 printReverse()를 호출합니다.
    3. getTotal()을 사용하여 Total: <sum>을 출력합니다.
    4. doubleAll()을 호출하여 수량을 수정합니다.
    5. After doubling:을 출력한 후 printForward()를 호출합니다.
    6. 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;
}
quiz icon실력 점검

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

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