2011-09-07 6 views
5

저는 C++ std::multimap을 사용하고 있으며 두 개의 다른 키를 반복해야합니다. 두 개의 범위를 만들고 그 범위를 반복적으로 반복하는 것 이외에도 효율적인 방법이 있습니까?std :: multimap 두 범위 가져 오기

std::pair<std::multimap<String, Object*>::iterator,std::multimap<String, Object*>::iterator> range; 
std::pair<std::multimap<String, Object*>::iterator,std::multimap<String, Object*>::iterator> range2; 

// get the range of String key 
range = multimap.equal_range(key1); 
range2 = multimap.equal_range(key2); 

for (std::multimap<String, Object*>::iterator it = range.first; it != range.second; ++it) 
{ 
    ... 
} 
for (std::multimap<String, Object*>::iterator it2 = range2.first; it2 != range2.second; ++it2) 
{ 
    ... 
} 
+2

왜 그것이 효율적이지 않다고 생각하십니까? –

+0

멀티 맵을 처음 사용하기에 너무 익숙하지 않습니다. 나는 그 루프에서 많은 일을 할 것이며, 동시에 두 가지 범위를 얻을 수있는 또 다른 작업이 있는지 궁금해하고 있습니다. –

+0

키가 겹치지 만 서로 같지 않은 키의 예를들 수 있습니까? 어쩌면 내 머리가 아프지 만, 열쇠에 대한 간단한 평등 확인이 그렇게 할 것 같습니다. 각 쿼리에 대해 상한과 하한을 구분하면 내게 의미가 있습니다. –

답변

3

당신이 시작 코드는 가장 간단는 다음과 같습니다

지금 그 일을하는 방식의 메신저입니다.

동일한 루프에서 두 범위를 반복하는 경우 두 개의 반복자 범위를 사용하는 사용자 정의 반복자를 만들 수 있습니다. 처음 반복 할 때까지 반복하고 두 번째 반복자를 전환 할 때까지 반복 할 수 있습니다. 모든 iterator 멤버를 직접 구현해야하기 때문에 이것은 가치가있는 것보다 더 많은 문제 일 것입니다.

편집 : 나는 이것을 overthinking했다; 두 개의 루프를 하나의 루프로 수정하는 것은 쉽습니다.

for (std::multimap<String, Object*>::iterator it = range.first; it != range2.second; ++it) 
{ 
    if (it == range.second) 
    { 
     it = range2.first; 
     if (it == range2.second) 
      break; 
    } 
    ... 
} 
+0

이것 역시 생각했습니다. 그러나이 두 키가 작동하려면 서로 옆에 있어야합니까? 예를 들어 내가 3 개의 키를 가지고 있고 1 위를 반복하고 싶은데 3 위는 그들과 2 등을 포함하지 않을 것입니까? 아니면 if 문으로 해결할 수 있습니까? –

+1

@Kaiser,'if' 문은 첫 번째 범위에서 두 번째 범위로의 전환을 처리합니다. 그들은 심지어 질서가있을 수 있습니다. 그들이 할 수없는 유일한 것은 교차합니다. 'range2'에'range.second'가 포함되면 무한 루프가 발생합니다. –

+0

아하이 봐요. 내 range2는 정적이며 range1은 항상 달라집니다. 그들은 결코 옳은 것을 교차 시키면 안된다. 다중 맵은 삽입시 정렬되기 때문에? –

3

부스트는 물론 이것을 수행합니다. Boost.Range와 그 join 함수를 사용하면 원하는 것을 얻을 수 있습니다. 자세한 내용은 Boost Range Library: Traversing Two Ranges Sequentially을 참조하십시오.

+0

감사합니다, 부스트가 보인다. 정말 강력합니다. 불행히도 우리 회사는 낡은 학교이며 새로운 것을 싫어합니다. 효율성에 대한 것이 아닌 편의성에 대해서는 비공식적으로 –

+0

으로 정해야합니다. 편의성에 관한 것입니다. –

0

당신은 C++에 액세스 할 수있는 경우 - 11 (비주얼 스튜디오 10 +, GCC-4.5 +)를하고 auto이 진짜 보석입니다 그것을 사용할 수 있습니다 : 그냥 열쇠를 테스트하는 것, 어쨌든

// get the range of String key 
auto range = multimap.equal_range(key1); 
auto range2 = multimap.equal_range(key2); 

for (auto it = range.first; it != range.second; ++it) 
{ 
    ... 
} 
for (auto it2 = range2.first; it2 != range2.second; ++it2) 
{ 
    ... 
} 

key2! = key1 인 경우에만 두 번째 루프를 수행하십시오. 루프에서 매번 반복자를 검사하는 것은 약간의 비용이 든다.

두 번째 첫 번째 범위의 std :: set_difference가 코드를 간소화 할 수 있습니다. 아마 std :: set_union 두 범위와 backininserter를 통해 세트에 삽입하면 복사본 하나만 얻을 수 있습니까?

일부 실험을 순서대로 수행 할 수 있습니다. 믹스에 첫 번째 추측을하는 것을 잊지 마십시오. 속도 측면에서 문제가되는 것은 당신을 놀라게 할 수 있습니다. 범위가 일반적으로 매우 길거나 루프 연산이 비싸지 않으면 여분의 부기에 골머리를 앓을만한 가치가 없을 수 있습니다.

관련 문제