2012-03-23 5 views
5

그래서 나는 pairs<string ,string>C++에서 쌍 요소 검색을 설정 하시겠습니까?

의 세트를 가지고 내가 먼저 내가 두 번째 반환 할에, 나는 그 문자열을 발견 한 경우, "최초의"한 쌍의에있을 것입니다 하나의 문자열을 검색 할 find()를 사용하려면 그 기능에서. 나의 현재의 시도가

..

myList::iterator i; 

i = theList.find(make_pair(realName, "*")); 

return i->second; 
+7

왜 '지도'를 사용하지 않습니까? 기타주의 사항 :'std :: set'이라면 왜'myList'라고 불 렸을까요? 'std :: pair'에 대한 비교 함수를 만들었습니까? 그것은 어떻게 생겼어? –

답변

2

이에 대한 std::set<std::pair<std::string, std::string> >을 사용할 수 있지만 한 쌍의 관계 연산자이 모두 요소를 필요하기 때문에이에 대한 사용자 지정 비교 대상이 필요합니다. 즉 실제로는 std::map<std::string, std::string>을 사용해야하는 것 같습니다.

+1

나는 동의하지 않는다, 의미는 확실히 다를 것이다, 특히 동일한 "열쇠"를 가진 몇몇 품목을 저장하는 무능력. '멀티 맵 (multimap) '은 의미론면에서 더 가까울 수 있지만 쌍의 고유성을 보장하지는 않는다. 요구 사항을 알지 못하면 대답은 실제로 어두운 곳에서의 촬영입니다 ... –

1

std::pair에 대한 <의 정의는 사전 식 순서를 구현하고 ""은 문자열의 최소 요소입니다. 이것을 결합하면 다음과 같습니다.

typedef std::pair<std::string, std::string> StringPair; 
typedef std::set<StringPair> Set; 

std::string const* find_first(Set const& s, std::string const& key) { 
    Set::const_iterator const it = s.lower_bound(std::make_pair(key, "")); 

    // Check that it actually points to a valid element whose key is of interest. 
    if (it == s.end() or it->first != key) { return 0; } 

    // Yata! 
    return &it->second; 
} 

트릭은 lower_bound을 적절히 사용하고 있습니다.

value을 비교하지 않는 첫 번째 요소를 가리키는 반복기를 반환합니다.

  • end()을 반환하는 경우, 다음 흥미로운 아무것도 찾지 못했습니다. 이것은 단지 범위의 첫 번째 요소를 반환하지만 내가 지적 할

  • 그렇지 않으면, it->first >= key 그래서 우리는 (아무 관심이 우리에게)이 > 경우 제거. 모든 요소에 관심이 있다면, 시도 : 이것은 누구의 첫 번째 요소 key 같다 s의 노드의 전체 범위를 반환합니다

    typedef std::pair<Set::const_iterator, Set::const_iterator> SetItPair; 
    
    SetItPair equal_range_first(Set const& s, std::string const& key) { 
        StringPair const p = std::make_pair(key, ""); 
        return std::make_pair(s.lower_bound(p), s.upper_bound(p)); 
    } 
    

    . 그런 다음 바로이 범위를 반복해야합니다 :

    for (Set::const_iterator it = range.first; it != range.second; ++it) { 
        // do something 
    } 
    

    을 그리고 당신도 lower_bound 또는 upper_bound의 반환은 끝이었다 또는 여부를 걱정할 필요가 없습니다.

    • lower_bound 경우 복귀 end()하고 있으므로 upper_bound를 수행하고 루프를 스킵
    • 노드에 lower_bound 점은 it->first > key 들면 다음 upper_bound는 동일한 노드를 가리킬 것이고, 루프는
    • 스킵되면

    그게 범위의 힘입니다 : 특별한 수표를 만들 필요가 없으며, 일치하지 않을 때 범위가 끝나기 때문에, 그들 위에있는 루프는 한 번 검사에서 건너 뜁니다.

  • +0

    두 번째 요소가 int 인 경우 어떻게됩니까? – user3522401

    6

    C++ 11은 사용할 수 있습니까?그래서 다음과 같이 호출 다음

    struct MatchFirst 
    { 
         MatchFirst(const string& realName) : realName(realName) {} 
    
         bool operator()(const pair<string, string>& val) { 
           return val.first == realName; 
         } 
    
         const string& realName; 
    }; 
    

    :

    auto it = find_if(theList.begin(), theList.end(), 
        [&](const pair<string, string>& val) -> bool { 
         return val.first == realName; 
        }); 
    
    return it->second; 
    

    또는 C++ 03

    먼저 펑터를 정의

    myList::iterator it = find_if(a.begin(), a.end(), MatchFirst(realName)); 
    return it->second; 
    

    이를 첫 번째 경기를 반환하지만로부터 질문, 그것은 당신이 기대하는 모든 것 같습니다.