문제

나는 잠시 자리를 비운 후 오래된 멜론의 먼지를 털어내려고 노력한 후 C++로 돌아왔습니다.

Java Iterator는 다음과 같은 메소드를 갖는 컨테이너에 대한 인터페이스입니다.hasNext(), next() 및 제거().hasNext()가 있다는 것은 그것을 의미합니다. 한계라는 개념이 있다 컨테이너가 통과되는 경우.

//with an Iterator
Iterator<String> iter = trees.iterator();
while (iter.hasNext()) 
{
    System.out.println(iter.next());
}

C++ 표준 템플릿 라이브러리에서 반복자는 연산자++ 및 연산자==를 지원하는 데이터 유형이나 클래스를 나타내는 것처럼 보이지만 한계라는 개념이 없다 내장되어 있으므로 다음 항목으로 넘어가기 전에 비교가 필요합니다.한계는 사용자가 두 개의 반복자를 비교하여 확인해야 합니다. 일반적인 경우 두 번째 반복자는 컨테이너 끝입니다.

vector<int> vec;
vector<int>::iterator iter;

// Add some elements to vector
v.push_back(1);
v.push_back(4);
v.push_back(8);

for(iter= v.begin(); iter != v.end(); iter++)
{
    cout << *i << " "; //Should output 1 4 8
}

여기서 흥미로운 부분은 C++에서 포인터가 배열에 대한 반복자라는 것입니다.STL은 기존의 것을 가져와서 이를 중심으로 규칙을 구축했습니다.

내가 놓친 것보다 더 미묘한 것이 있습니까?

도움이 되었습니까?

해결책

예, 개념적 차이가 큽니다.C++에서는 반복자의 다양한 "클래스"를 활용합니다.일부는 무작위 액세스(Java와 달리)에 사용되고 일부는 순방향 액세스(예: Java)에 사용됩니다.다른 것들은 데이터를 쓰는 데 사용되지만(예를 들어, transform).

반복자 개념을 참조하세요. C++ 문서:

  • 입력 반복자
  • 출력 반복자
  • 순방향 반복자
  • 양방향 반복자
  • 랜덤 액세스 반복자

이는 Java/C#의 보잘것없는 반복자에 비해 훨씬 더 흥미롭고 강력합니다.이러한 규칙이 C++0x를 사용하여 성문화되기를 바랍니다. 개념.

다른 팁

아마도 좀 더 이론적일 것입니다.수학적으로 C++의 컬렉션은 반복자의 반 개방 간격, 즉 컬렉션의 시작을 가리키는 하나의 반복자와 컬렉션의 시작을 가리키는 하나의 반복자로 설명할 수 있습니다. 바로 뒤에 마지막 요소.

이 컨벤션은 다양한 가능성을 열어줍니다.알고리즘이 C++에서 작동하는 방식으로 더 큰 컬렉션의 하위 시퀀스에 모두 적용될 수 있습니다.Java에서 이러한 작업을 수행하려면 다른 반복자를 반환하는 기존 컬렉션 주위에 래퍼를 만들어야 합니다.

반복자의 또 다른 중요한 측면은 이미 Frank가 언급했습니다.반복자의 개념은 다양합니다.Java 반복자는 C++의 입력 반복자에 해당합니다. 즉,이는 한 번에 한 단계씩만 증가할 수 있고 뒤로 이동할 수 없는 읽기 전용 반복자입니다.

다른 극단에는 C++의 무작위 액세스 반복기 개념과 정확히 일치하는 C 포인터가 있습니다.

전체적으로 C++는 C 포인터나 Java 반복자보다 훨씬 더 다양한 작업에 적용할 수 있는 훨씬 더 풍부하고 순수한 개념을 제공합니다.

언급한 바와 같이 Java 및 C# 반복자는 위치(상태)와 범위(값)가 혼합된 방식으로 설명하는 반면, C++ 반복자는 위치와 범위의 개념을 분리합니다.C++ 반복자는 '나는 어디로 갈 수 있는가?'와 별도로 '나는 지금 어디에 있는가'를 나타냅니다.

Java 및 C# 반복자는 복사할 수 없습니다.이전 위치를 복구할 수 없습니다.일반적인 C++ 반복자는 가능합니다.

고려하다 이 예:

// for each element in vec
for(iter a = vec.begin(); a != vec.end(); ++a){
  // critical step!  We will revisit 'a' later.
  iter cur = a; 
  unsigned i = 0;
  // print 3 elements
  for(; cur != vec.end() && i < 3; ++cur, ++i){
      cout << *cur << " ";
  }
  cout << "\n";
}

프로그램 출력을 보려면 위 링크를 클릭하세요.

이 다소 어리석은 루프는 시퀀스(순방향 반복자 의미론만 사용)를 통해 진행되며, 3개 요소의 각 연속 하위 시퀀스를 정확히 한 번 인쇄합니다(그리고 마지막에 몇 개의 더 짧은 하위 시퀀스).그러나 N개의 요소와 3개가 아닌 줄당 M개의 요소를 가정하면 이 알고리즘은 여전히 ​​O(N*M) 반복자 증분 및 O(1) 공간이 됩니다.

Java 스타일 반복자에는 위치를 독립적으로 저장하는 기능이 부족합니다.당신은

  • 예를 들어 반복할 때 기록을 저장하기 위해 M 크기의 배열을 사용하여 O(1) 공간을 잃습니다.
  • 목록을 N 번 순회해야 하므로 O(N^2+N*M) 시간이 소요됩니다.
  • 또는 GetAt 멤버 함수와 함께 구체적인 배열 유형을 사용하면 일반성과 연결된 목록 컨테이너 유형을 사용하는 기능이 손실됩니다.

이 예에서는 순방향 반복 메커니즘만 사용되었으므로 목록에서 다음과 같이 교체할 수 있었습니다. 아무 문제 없습니다.이는 검색, 지연된 초기화 및 평가, 정렬 등과 ​​같은 일반 알고리즘을 작성하는 데 중요합니다.

상태를 유지할 수 없다는 점은 매우 적은 수의 알고리즘이 구축되는 C++ STL 입력 반복자와 가장 밀접하게 일치합니다.

배열 요소에 대한 포인터는 실제로 배열에 대한 반복자입니다.

당신이 말했듯이 Java에서 반복자는 C++보다 기본 컨테이너에 대해 더 많은 지식을 가지고 있습니다.C++ 반복자는 일반적이며 of iterator는 모든 범위를 나타낼 수 있습니다.이는 컨테이너의 하위 범위, 여러 컨테이너에 대한 범위일 수 있습니다(참조: http://www.justsoftwasolutions.co.uk/articles/pair_iterators.pdf 또는 http://www.boost.org/doc/libs/1_36_0/libs/iterator/doc/zip_iterator.html) 또는 숫자 범위(참조: http://www.boost.org/doc/libs/1_36_0/libs/iterator/doc/counting_iterator.html)

반복자 카테고리는 주어진 반복자로 수행할 수 있는 작업과 수행할 수 없는 작업을 식별합니다.

나에게 근본적인 차이점은 Java Iterator는 항목 사이를 가리키는 반면 C++ STL 반복자는 항목을 가리킨다는 것입니다.

C++ 반복자는 포인터 개념을 일반화한 것입니다.이를 통해 더 넓은 범위의 상황에 적용할 수 있습니다.이는 임의의 범위를 정의하는 등의 작업을 수행하는 데 사용할 수 있음을 의미합니다.

Java 반복자는 상대적으로 바보 같은 열거자입니다(C#만큼 나쁘지는 않지만;최소한 Java에는 ListIterator가 있으며 컬렉션을 변경하는 데 사용할 수 있습니다.

반복자는 배열의 내용을 순서대로 반복하는 사소한 경우의 포인터와 동일합니다.반복자는 다양한 소스로부터 객체를 제공할 수 있습니다.데이터베이스, 파일, 네트워크, 기타 계산 등에서

C++ 라이브러리(이전에는 STL로 알려진 부분) 반복자는 포인터와 호환되도록 설계되었습니다.포인터 연산이 없는 Java는 프로그래머 친화적인 자유를 누렸습니다.

C++에서는 결국 한 쌍의 반복자를 사용해야 합니다.Java에서는 반복자 또는 컬렉션을 사용합니다.반복자는 알고리즘과 데이터 구조 사이를 연결하는 역할을 합니다.1.5 이상용으로 작성된 코드는 특정 알고리즘이나 데이터 구조를 구현하지 않는 한 반복자를 언급할 필요가 거의 없습니다(다양한 프로그래머는 이를 수행할 필요가 없음).Java가 동적 다형성 하위 집합을 사용하므로 처리하기가 훨씬 쉽습니다.

차이점에 대한 좋은 답변이 많이 있지만 Java 반복자에서 가장 짜증나는 점은 강조되지 않은 것입니다. 즉, 현재 값을 여러 번 읽을 수 없습니다.이는 특히 반복자를 병합할 때 많은 시나리오에서 매우 유용합니다.

C++에는 반복기를 진행하고 현재 값을 읽는 방법이 있습니다.해당 값을 읽어도 반복이 진행되지는 않습니다.여러 번 읽을 수 있도록 말이죠.이는 Java 반복자에서는 불가능하며 결국 이를 수행하는 래퍼를 생성하게 됩니다.

참고 사항:래퍼를 만드는 쉬운 방법 중 하나는 기존 래퍼를 사용하는 것입니다.PeekingIterator 구아바에서.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top