std :: vector의 반복자 색인을 얻는 가장 효과적인 방법은 무엇입니까? 현재 가리키는

벡터를 반복하고 반복자가 현재 가리키는 색인이 필요합니다. AFAIK는 두 가지 방법으로 수행 할 수 있습니다.

  • it - vec.begin()
  • std::distance(vec.begin(), it)

이 방법의 장단점은 무엇입니까?



답변

내가 선호하는 it - vec.begin()나빈에 의해 주어진 반대 이유에 대해 정확하게 : 그렇게 하지 않을 당신이 목록에 벡터를 변경하면 컴파일합니다. 반복 할 때마다이 작업을 수행하면 O (n) 알고리즘을 O (n ^ 2) 알고리즘으로 쉽게 전환 할 수 있습니다.

또 다른 옵션은 반복 중에 컨테이너에서 뛰어 다니지 않으면 인덱스를 두 번째 루프 카운터로 유지하는 것입니다.

참고 : it컨테이너 반복자의 일반 이름입니다 std::container_type::iterator it;.


답변

std::distance(vec.begin(), it)코드를 변경하지 않고 컨테이너를 변경할 수 있기 때문에 선호합니다 . 예를 들어, 랜덤 액세스 반복자를 제공하지 않는 std::list대신 사용하기로 결정하면 std::vector코드는 여전히 컴파일됩니다. std :: distance는 반복자 특성에 따라 최적의 방법을 선택하므로 성능 저하가 없습니다.


답변

UncleBens와 Naveen에서 알 수 있듯이 두 가지 이유가 있습니다. 어떤 행동이 “더 나은”행동인지에 따라 달라집니다. 일정한 시간 행동을 보장하고 싶습니까, 아니면 필요할 때 선형 시간으로 넘어 가기를 원하십니까?

it - vec.begin()일정한 시간 operator -이 걸리지 만 무작위 액세스 반복자에서만 정의되므로 코드는 목록 반복자와 함께 전혀 컴파일되지 않습니다.

std::distance(vec.begin(), it) 모든 반복자 유형에 대해 작동하지만 임의 액세스 반복자에서 사용되는 경우 일정 시간 동안 만 작동합니다.

어느 쪽도 “더 나은”것이 아닙니다. 필요한 것을하는 것을 사용하십시오.


답변

나는 이것을 좋아한다 : it - vec.begin(), 나에게 그것은 “처음부터의 거리”를 분명히 나타 내기 때문이다. 반복자를 사용하면 산술 측면에서 생각하는 데 익숙하므로 -부호가 가장 분명한 표시기입니다.


답변

이미 제한하는 경우 / A를 사용하여 알고리즘을 하드 코딩 std::vector::iteratorstd::vector::iterator만, 정말없이 사용하여 종료됩니다하지 않는 방법. 알고리즘 중 하나를 선택하면 차이가 생길 수있는 시점을 넘어서 알고리즘이 이미 구체화되었습니다. 둘 다 정확히 같은 일을합니다. 그것은 개인적인 취향의 문제 일뿐입니다. 나는 개인적으로 명시 적 뺄셈을 사용합니다.

반면에 알고리즘에서 더 높은 수준의 일반성을 유지하려는 경우, 즉 언젠가 미래에 다른 반복자 유형에 적용될 가능성을 허용하기 위해 최선의 방법은 의도에 달려 있습니다. . 여기에서 사용할 수있는 반복자 유형과 관련하여 얼마나 제한적인지에 따라 다릅니다.

  • 명시 적 뺄셈을 사용하는 경우 알고리즘은 다소 좁은 반복자 클래스 인 임의 액세스 반복자로 제한됩니다. (이것은 지금 당신이 얻는 것입니다 std::vector)

  • 을 사용 distance하면 알고리즘이 훨씬 광범위한 반복자 클래스 인 입력 반복자를 지원합니다.

물론, distance비 랜덤 액세스 반복자에 대한 계산 은 일반적으로 비효율적 인 작업입니다 (반복 액세스 조작의 경우 빼기만큼 효율적 임). 알고리즘 효율성에 따라 비 랜덤 액세스 반복자 에 적합한 지 결정하는 것은 사용자의 몫 입니다. 결과적으로 효율성의 손실은 알고리즘을 완전히 쓸모 없게 만드는 지점으로 치명적입니다. 그러면 빼기를 더 잘 사용해야 비효율적 인 사용을 금지하고 사용자가 다른 반복자 유형에 대한 대체 솔루션을 강요해야합니다. 비 랜덤 액세스 반복기의 효율성이 여전히 사용 가능한 범위에있는 경우 랜덤 액세스 반복기 distance에서 알고리즘이 더 잘 작동한다는 사실을 사용 하고 문서화 해야 합니다.


답변

따르면 http://www.cplusplus.com/reference/std/iterator/distance/ 때문에, vec.begin()A는 랜덤 액세스 반복자 거리 방법은 사용 -연산자.

따라서 성능 관점에서 볼 때 대답은 동일하지만 distance()코드를 읽고 이해해야하는 사람이 있으면 사용하기 가 더 쉽습니다.


답변

나는 -변형 std::vector만을 사용한다 -의미가 분명하고 조작의 단순성 (포인터 빼기 이상은 아닙니다)은 구문 ( distance, 다른 한편으로는 피타고라스와 같은 소리 )으로 표현됩니다 먼저 읽지 않습니까?). UncleBen이 지적했듯이 실수로로 변경되면 -정적 어설 션으로도 작동 vector합니다 list.

또한 나는 그것이 훨씬 흔하다고 생각합니다-그것을 증명할 숫자가 없습니다. 마스터 논증 :it - vec.begin() 소스 코드가 짧아 타이핑 작업이 적고 공간이 절약됩니다. 귀하의 질문에 대한 정답이 미각의 문제로 귀결된다는 것이 명백하기 때문에, 이것은 또한 유효한 주장 일 수 있습니다 .