2012-03-23 21 views
5

तो मैं pairs<string ,string>सी ++ जोड़ी तत्व के लिए खोज सेट करें?

का एक सेट है और मैं एक एकल स्ट्रिंग, जिसमें जोड़ी के "प्रथम" होगा के लिए खोज करने के लिए find() का उपयोग करने के पहले मैं दूसरा वापस जाने के लिए चाहते हैं, तो यदि मैं उस स्ट्रिंग को खोजने के लिए चाहते हैं उस समारोह से।

मेरे वर्तमान प्रयास है ..

myList::iterator i; 

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

return i->second; 
+7

आप 'मानचित्र' का उपयोग क्यों नहीं कर रहे हैं? अन्य नोट्स: यदि यह 'std :: set' है, तो इसे 'myList' क्यों कहा जाता है? क्या आपने 'std :: pair's के लिए तुलनात्मक फ़ंक्शन बनाया है? यह कैसा दिखता है? –

उत्तर

2

आप इस के लिए std::set<std::pair<std::string, std::string> > उपयोग कर सकते हैं, बल्कि इसलिए जोड़ी की संबंधपरक ऑपरेटर इस के लिए दोनों तत्वों लेता है तो आप इस के लिए एक कस्टम तुलना वस्तु की आवश्यकता होगी। ऐसा कहा जाता है, ऐसा लगता है कि आपको वास्तव में std::map<std::string, std::string> का उपयोग करना चाहिए।

+1

मैं असहमत हूं, अर्थशास्त्र काफी अलग होगा, विशेष रूप से एक ही "कुंजी" के साथ कई वस्तुओं को स्टोर करने में असमर्थता। एक 'मल्टीमैप' अर्थशास्त्र के मामले में करीब हो सकता है, लेकिन फिर जोड़ी की विशिष्टता की गारंटी नहीं देगा जो वांछनीय भी हो सकता है। आवश्यकता जानने के बिना, आपका जवाब वास्तव में अंधेरे में एक शॉट है ... –

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 तो हम > मामले की (हमारे लिए कोई दिलचस्पी नहीं की) छुटकारा पाने

मैं बाहर बिंदु होगा, हालांकि कि यह केवल सीमा के पहले तत्व देता है। आप सभी तत्वों में रुचि रखते हैं, की कोशिश:

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)); 
} 

यह s जिसका पहला तत्व key के बराबर है में नोड्स की पूरी रेंज वापस आ जाएगी। इसके बाद आप सिर्फ इस सीमा पर पुनरावृति करने के लिए है:

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

क्या सी ++ 11 स्वीकार्य है?

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

return it->second; 

या सी ++ 03 में, पहले एक functor निर्धारित करें:

struct MatchFirst 
{ 
     MatchFirst(const string& realName) : realName(realName) {} 

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

     const string& realName; 
}; 

तो यह बहुत की तरह फोन:

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

यह केवल पहला मैच वापस आ जाएगी, लेकिन से अपने सवाल, ऐसा लगता है कि आप सब कुछ उम्मीद कर रहे हैं।