본문 바로가기
IT, 컴퓨터

[C++] 자료구조 Iterator의 원리와 사용법

by 별찌파파 2024. 1. 13.
728x90
반응형
SMALL

Photo by Markus Spiske on Unsplash

Iterator ?

C++에서 Iterator(반복자)는 컨테이너의 요소를 순회하거나 접근하는 데 사용되는 개념입니다. Iterator는 일반적으로 포인터와 유사하게 동작하지만, 포인터와는 달리 특정 컨테이너의 내부 구조에 의존하지 않고 일반화된 방식으로 요소에 접근할 수 있습니다. STL(Standard Template Library)에서 많이 사용되며, 여러 종류의 컨테이너와 함께 사용됩니다.

아래는 C++에서 iterator에 대한 기본적인 내용입니다:

  1. 종류:
    • Input Iterator: 읽기 전용으로, 순차적으로 한 번에 하나의 요소만 읽을 수 있습니다.
    • Output Iterator: 쓰기 전용으로, 순차적으로 한 번에 하나의 요소만 쓸 수 있습니다.
    • Forward Iterator: 순방향으로 이동이 가능하며, Input Iterator의 모든 기능을 포함합니다.
    • Bidirectional Iterator: 양방향으로 이동이 가능하며, Forward Iterator의 모든 기능을 포함합니다.
    • Random Access Iterator: 임의 접근이 가능하며, 양방향 Iterator의 모든 기능을 포함합니다.
  2. 사용법:
    • Iterator는 주로 컨테이너의 시작 지점을 가리키는 begin()과 끝 지점을 가리키는 end() 함수를 통해 얻습니다.
    • begin()은 첫 번째 요소를 가리키는 iterator를 반환하며, end()는 마지막 다음 위치를 가리키는 iterator를 반환합니다.
      std::vector<int> myVector = {1, 2, 3, 4, 5};
      
      // Iterator 얻기
      std::vector<int>::iterator itBegin = myVector.begin();
      std::vector<int>::iterator itEnd = myVector.end();
      
      // 순회
      for (std::vector<int>::iterator it = itBegin; it != itEnd; ++it) {
          std::cout << *it << " ";
      }​
  3. 범위 기반 for 루프:
    • C++11부터는 범위 기반 for 루프를 통해 iterator를 사용하기가 더 간편해졌습니다.
      std::vector<int> myVector = {1, 2, 3, 4, 5};
      
      // 범위 기반 for 루프
      for (const auto& element : myVector) {
          std::cout << element << " ";
      }​
  4. Iterator 연산:
    • *it: 현재 iterator가 가리키는 요소에 접근.
    • ++it 또는 it++: iterator를 다음 위치로 이동.
    • --it 또는 it--: iterator를 이전 위치로 이동.
    • it1 + n 또는 it1 - n: iterator를 n만큼 이동.
    • it1 == it2 또는 it1 != it2: 두 iterator가 같은지 비교.

Iterator는 일반적으로 컨테이너의 내부 구조에 대한 의존성을 낮춰주므로, 코드를 보다 일반화하고 재사용 가능하게 만들어 줍니다.

 

 

Iterator 예제

 

C++에서는 iterator를 사용하여 정방향 및 역방향으로 순회할 수 있습니다. 아래는 정방향 및 역방향으로 순회하는 예제 코드입니다. 이 예제에서는 std::vector를 사용하고 있습니다.

#include <iostream>
#include <vector>

int main() {
    // 정수를 저장하는 vector 생성
    std::vector<int> numbers = {1, 2, 3, 4, 5};

    // vector의 시작과 끝을 가리키는 iterator 얻기
    std::vector<int>::iterator itBegin = numbers.begin();
    std::vector<int>::iterator itEnd = numbers.end();

    // 정방향으로 순회하며 출력
    std::cout << "정방향 순회: ";
    for (std::vector<int>::iterator it = itBegin; it != itEnd; ++it) {
        std::cout << *it << " ";
    }

    std::cout << std::endl;

    // 역방향으로 순회하며 출력
    std::cout << "역방향 순회: ";
    for (std::vector<int>::reverse_iterator rit = numbers.rbegin(); rit != numbers.rend(); ++rit) {
        std::cout << *rit << " ";
    }

    return 0;
}

 

이 코드에서는 std::vector<int>를 사용하여 정수를 저장하고, 정방향으로 순회하는 부분과 역방향으로 순회하는 부분이 구현되어 있습니다. begin()end() 함수로 얻은 iterator는 정방향으로, rbegin()rend() 함수로 얻은 reverse iterator는 역방향으로 vector를 순회합니다.

 

<결과>

정방향 순회: 1 2 3 4 5
역방향 순회: 5 4 3 2 1

 

Iterator의 장점과 단점

 

 

Iterator는 프로그래밍에서 유용한 도구로 간주되지만, 사용하는 상황에 따라 장점과 단점이 있습니다.

 

Iterator의 장점:

  1. 일반화된 접근: Iterator는 특정 컨테이너에 종속되지 않기 때문에, 컨테이너의 내부 구조에 대한 의존성을 낮추고 일반적인 방식으로 요소에 접근할 수 있습니다.
  2. 다양한 컨테이너 지원: Iterator는 다양한 종류의 컨테이너에 대해 동일한 인터페이스를 제공하므로, 일관된 방식으로 여러 종류의 자료 구조를 다룰 수 있습니다.
  3. 범위 기반 for 루프: C++11부터 도입된 범위 기반 for 루프를 통해 Iterator를 사용하는 것이 간편해졌습니다.
  4. 알고리즘과의 통합: STL에서 제공하는 다양한 알고리즘들은 Iterator와 함께 사용되어 효율적이고 일관된 데이터 처리를 가능하게 합니다.

Iterator의 단점:

  1. 복잡성: Iterator를 사용하면 코드가 조금 더 복잡해질 수 있습니다. 특히 초기 학습 단계에서는 이해하기 어려울 수 있습니다.
  2. 오버헤드: Iterator를 사용하면 추가적인 오버헤드가 발생할 수 있습니다. 특히 매우 단순한 작업을 수행하는 경우에는 이 오버헤드가 불필요할 수 있습니다.
  3. 일부 자료구조에서의 한계: Iterator는 모든 자료 구조에서 항상 효율적으로 작동하지 않을 수 있습니다. 특히 특정한 조건에서는 일부 컨테이너에서 반복 작업이 더 효율적일 수 있습니다.
  4. 언어에 대한 추가 학습 필요: Iterator를 사용하려면 프로그래머가 어떻게 작동하는지 이해해야 합니다. 어떤 상황에서 어떤 종류의 iterator를 선택해야 하는지 등에 대한 지식이 필요합니다.

요약하면, Iterator는 다양한 장점을 제공하지만, 코드의 복잡성과 일부 상황에서의 오버헤드 등의 단점도 고려해야 합니다. Iterator를 적절히 사용하면 코드의 일반화와 모듈성을 향상시킬 수 있습니다.

728x90
반응형
LIST