2012-04-27 2 views
2

입니다. 벡터에 반복자가 있습니다. iterator가 가리키는 인덱스를 알고 싶습니다. 그래서 나는 따라 갔지만 확실하지 않습니다. 당신이 비록마다 루프를 실행하면이 저하 될 수 있다는다음 색인을 가리키는 반복자는

int temp = -1; 
std::vector <int> ::iterator f; 

for (f=eFace[e].begin(); f!=eFace[e].end(); ++f) 
{ 
    if (*f == face) 
{ 
    switch (f-eFace[e].begin()) 
    { 
     case 0: 
     temp = 5;         
     break; 
     case 1: 
     temp = 3; 
     break; 
     case 2: 
     temp = 4; 
     break; 
     case 3: 
     temp = 1; 
     break; 
     case 4: 
     temp = 2; 
     break; 
     case 5: 
     temp = 0; 
     break; 
      default: 
     throw; 
    } 

    break; 
    } 
} 
+1

큰 목표는 무엇입니까? 당신은 반복자와 인덱스가 동시에 필요합니까? –

+0

@phresnel, 나는 이것을 출력하는 데 가장 유용하다고 생각한다. 나는 목표가 같을 것이라고 추측한다. – chris

답변

2

왜이 같은하지 뭔가 : 귀하의 질문에 대한

std::vector <int> ::iterator f; 

int index = 0; 

for (f=eFace[e].begin(); f!=eFace[e].end(); ++f) 
{ 
    // do sth 

    index++; 
} 
+1

@larsmans : 증분은 일정한 시간 작업입니다. –

+1

큰 루프에서는 매번 거리를 빼거나 호출 할 때보 다 시간에 상당한 차이가 있습니다. – chris

+2

'f'의 증분과 함께'index'의 증분을 두어 동기화를 피할 수없는 이유는 무엇입니까? –

4
std::vector<int>::size_type index = std::distance (eFace [e].begin(), f); 

참고. 벡터에 대한 또 다른 옵션은 다음과 같습니다

벡터 아래 스티브 Jessop에 의해 지적, 뺄셈 정의가 요구되는 랜덤 액세스 반복자를 사용하기 때문에이 작동
std::vector<int>::size_type index = f - eFace [e].begin(); 

.

+0

실제로 표준에 의해 요구되는지 여부는 확실하지 않지만,'std :: distance'가 랜덤 액세스 (벡터 반복자)로 태그 된 반복자에 대해 일정한 시간 복잡성을 갖고 있지 않다면, 이것은 매우 불량합니다. 그것은 준수한다. 랜덤 액세스 반복자에 대한 뺄셈은'b - a == (a

+0

@SteveJessop, 흥미로운 점입니다. 나는 빼기가 그런 식으로 구현되었다는 것을 몰랐다. 내 대답은 인덱스 변수를 설정하고 그것을 증가시키는 두 가지 다른 부분보다 더 한 줄 접근법을 지적했다. 더 큰 루프에서는 오히려 비효율적입니다. – chris

+0

실제로 나는 뺄셈 *이 그런 식으로 구현되지 않는다고 기대한다. 결과가 그 값으로 표준에 정의되어 있다는 것이다. 그래서 우리가 '거리'의 어리 석음으로 느린 구현에 대해 추측한다면, 우리는 뺄셈 또한 어리 석다는 것을 추측 할 수 있습니다.실제로, 그들은 실제 사용을 위해 어떤 구현에 있어서도 빠를 것입니다. Btw, 벡터의 빼기 작업을하는 것은 저장소가 연속적이지 않다는 것입니다. 반복자는 임의 액세스이므로 빼기를 정의해야합니다. 예를 들어,'deque'는 연속하지 않는 저장 공간을 사용하지만 iterator 빼기도 마찬가지입니다. –

0

"나는 가리키는 반복자를 수행하는 인덱스 알고 싶어요." std::vector<int>::iterator f = eFace.begin();이라고 말하면 인덱스 접근법과 비슷한 인터레이터를 std::vector<int>::size_type i = 0;이라고합니다. 당신이 eFace.begin()!= eFace.end()for 루프 벡터를 걷고 때 i = 0!= eFace.size()를 사용하는 것과 같은 방법을 사용 반복자와

.

적어도 나는 그것이 원래 질문이 무엇인지 생각합니다.

2

더 명확한 코드를 얻는 것이 훨씬 쉽습니다.

첫째, 벡터의 값을 찾는 :

// Returns the index of `face` in `vec`. 
// If `face` is not present in `vec`, returns `vec.size()`. 
size_t findFaceIndex(int const face, std::vector<int> const& vec) { 
    std::vector<int>::const_iterator const it = 
     std::find(vec.begin(), vec.end(), face); 

    return it - vec.begin(); 
} 

그리고 지금 매핑 :

static int const FaceMap[] = { 5, 3, 4, 1, 2, 0 }; 
static size_t const FaceMapSize = sizeof(FaceMap)/sizeof(int); 

// Translate face index into ... 
int faceIndexToX(size_t const index) { 
    if (index >= FaceMapSize) { throw std::runtime_error("out of bounds"); } 
    return FaceMap[index]; 
} 
+0

그 중 첫 번째는 물론 템플릿 화 될 수 있습니다. 일반적으로 누군가가 선형 검색을 사용하므로 std :: find를 사용하면 경고 기호가 나타납니다. 아주 드문 경우이지만, 소장품은 드물지만, 소량이라고합니다. 당신의 두 번째 해결책은 std :: runtime_exception과 같은 예외는 없지만 (runtime_error가 있지만 std :: out_of_range가 아마도 vector :: throw와 같이 던질 때 더 좋은 방법 일 것입니다. – CashCow

+0

@CashCow : 나는'std :: array'를 고려했다. 그러나 OP가 C++ 11에 대해 잘 모르겠다. 물론 훨씬 쉽다. –

0

어쨌든 반복자가있을 때 당신이 배열의 인덱스가 필요한 이유를 궁금해? iterator가 무작위 접근을 제공한다면 begin()에서 뺄 수 있습니다.하지만 인덱스가 너무 중요하다면 반복자 라기보다는 코드를 사용하는 것이 더 낫지 않을지 궁금합니다. 물론 코드에 대한 액세스 권한이 있는지 여부에 달려 있습니다 그것을 리펙토링하는 것.

당신이 스위치로 달성하고자하는 것이 무엇인지 잘 모르겠지만 값을 맵핑하는 것이라면 아마도 희소 벡터가 훨씬 더 적절할 것입니다.

관련 문제