2009-02-11 11 views
26

मैं विधि को खोजने पता std :: नक्शा में आपूर्ति कुंजी पाता है और तत्व को एक इटरेटर लौट आते हैं। क्या मूल्य खोजने और तत्व के लिए इटेटरेटर प्राप्त करने के लिए वैसे भी है? मुझे क्या करना है std :: map में निर्दिष्ट मान मौजूद है। मैंने मानचित्र में सभी वस्तुओं को लूप करके और तुलना करके ऐसा किया है। लेकिन मैं जानना चाहता था कि इसके लिए कोई बेहतर दृष्टिकोण है।जांच की जा रही मूल्य एक std :: नक्शे में मौजूद - सी ++

यहाँ मैं

bool ContainsValue(Type_ value) 
{ 
    bool found = false; 
    Map_::iterator it = internalMap.begin(); // internalMap is std::map 
    while(it != internalMap.end()) 
    { 
     found = (it->second == value); 
     if(found) 
      break; 
     ++it; 
    } 
    return found; 
} 

क्या लिखा है संपादित

है कैसे आंतरिक रूप से एक और नक्शा जो मूल्य, कुंजी संयोजन को संग्रहीत करता है का उपयोग कर के बारे में। तो मैं इसे खोजने के लिए कॉल कर सकते हैं? पता है() std :: मानचित्र अनुक्रमिक खोज कर रहा है?

धन्यवाद

उत्तर

19

बनाने के लिए आप boost::multi_index का उपयोग कर सकते हैं - आप त्वरित लुकअप करने के लिए जोड़ी के किसी भी मान का उपयोग कर सकते हैं।

+0

आपने मुझे इसे हराया :) अच्छा जवाब। –

2

नहीं, आप std :: नक्शे पर पाश करने के लिए है और मैन्युअल रूप से सभी मूल्यों की जाँच करें। आप जो करना चाहते हैं उसके आधार पर, आप std :: map को एक साधारण वर्ग में लपेट सकते हैं जो मानचित्र में डाले गए सभी मानों को आसानी से खोज-योग्य करने में सक्षम करता है और डुप्लिकेट की अनुमति नहीं देता है, जैसे कि std ::सेट। std :: नक्शे से विरासत नहीं है (यह एक आभासी नाशक नहीं है!), लेकिन यह लपेट ताकि आप कुछ इस तरह कर सकते हैं:

WrappedMap my_map< std::string, double >; 
my_map[ "key" ] = 99.0; 
std::set<double> values = my_map.values(); // should give back a set with only 99.0 in it 

अपने खुद के रोलिंग के लिए एक वैकल्पिक करने के लिए किया जाएगा बूस्ट बिडरेक्शनल मानचित्र का उपयोग करें, जो आसानी से नीचे या Google द्वारा पोस्ट में पाया जाता है।

यह वास्तव में इस बात पर निर्भर करता है कि आप क्या करना चाहते हैं, आप कितनी बार इसे करना चाहते हैं, और बूस्ट का उपयोग करके और स्थापित करने के विरुद्ध अपनी छोटी रैपर कक्षा को रोल करना कितना मुश्किल है। मुझे बूस्ट पसंद है, इसलिए यह जाने का एक अच्छा तरीका है - लेकिन अपनी खुद की रैपर कक्षा बनाने के बारे में कुछ अच्छा और पूरा है। आपके पास सीधे संचालन की जटिलता को समझने का लाभ है, और आपको बूस्ट बिडरेक्शनल मानचित्र द्वारा प्रदान की जाने वाली मान => कुंजी की पूर्ण रिवर्स मैपिंग की आवश्यकता नहीं हो सकती है।

+0

वह तत्व के लिए एक पुनरावर्तक चाहता है, तो आप एक सेट <> के बजाय दूसरे मानचित्र <> का उपयोग करना चाहते हैं। –

6

बढ़ावा के द्विदिश नक्शे में देखो: http://www.boost.org/doc/libs/1_38_0/libs/bimap/doc/html/index.html

यह दोनों मूल्यों एक प्रमुख की तरह काम कर सकते हैं।

अन्यथा, पुनरावृत्ति जाने का तरीका है।

14

कैसे आंतरिक रूप से एक और नक्शा जो मूल्य, कुंजी संयोजन को संग्रहीत करता है का उपयोग कर के बारे में। तो मैं इसे खोजने के लिए कॉल कर सकते हैं?

हां: दो मानचित्र बनाए रखें, एक मानचित्र के साथ एक प्रकार की कुंजी का उपयोग करके और दूसरा दूसरे का उपयोग करें।

क्या पता है() std :: मानचित्र अनुक्रमिक खोज कर रहा है?

नहीं, यह एक क्रमबद्ध पेड़ की बाइनरी खोज है: इसकी गति ओ (लॉग (एन)) है।

+0

यह समझ में आता है। तो दो नक्शे बनाए रखने से अनुक्रमिक रूप से खोज और मूल्य खोजने से अच्छा प्रदर्शन होगा, है ना? –

+3

कुछ भी डालने या हटाने के लिए दो बार लंबा लगेगा (इसके बजाय दो मानचित्रों का उपयोग करके); लेकिन बड़ी संख्या में तत्वों के लिए, खोज बहुत तेज हो जाएगा क्योंकि ओ (लॉग (एन)) अनुक्रमिक खोज के लिए आवश्यक ओ (एन) से बहुत छोटा है। – ChrisW

+0

ग्रेट क्रिस। धन्यवाद। –

15

यदि आपके पास उत्कृष्ट boost लाइब्रेरी तक पहुंच है तो आपको का उपयोग bidirectional map बनाने के लिए करना चाहिए क्योंकि मार्क कहता है। एक std :: मानचित्र के विपरीत यह आपको कुंजी या मान से देखने की अनुमति देता है।

आप केवल एसटीएल निम्नलिखित कोड चाल (मानचित्र के किसी भी प्रकार जहां mapped_type ऑपरेटर == का समर्थन करता है के साथ काम करने वाली टेम्प्लेट) करना होगा सौंपने के लिए है, तो:

#include <map> 
#include <string> 
#include <algorithm> 
#include <iostream> 
#include <cassert> 

template<class T> 
struct map_data_compare : public std::binary_function<typename T::value_type, 
                 typename T::mapped_type, 
                 bool> 
{ 
public: 
    bool operator() (typename T::value_type &pair, 
        typename T::mapped_type i) const 
    { 
     return pair.second == i; 
    } 
}; 


int main() 
{ 
    typedef std::map<std::string, int> mapType; 

    mapType map; 

    map["a"] = 1; 
    map["b"] = 2; 
    map["c"] = 3; 
    map["d"] = 4; 
    map["e"] = 5; 

    const int value = 3; 

    std::map<std::string, int>::iterator it = std::find_if(map.begin(), map.end(), std::bind2nd(map_data_compare<mapType>(), value)); 

    if (it != map.end()) 
    { 
     assert(value == it->second); 
     std::cout << "Found index:" << it->first << " for value:" << it->second << std::endl; 
    } 
    else 
    { 
     std::cout << "Did not find index for value:" << value << std::endl; 
    } 
} 
-3

संभव है कि मुझे नहीं पता पूरी तरह से समझें कि आप क्या करने की कोशिश कर रहे हैं। लेकिन यह जांचने के लिए कि मानचित्र में कोई मान है या नहीं, मुझे विश्वास है कि आप std::map का निर्माण find में कर सकते हैं।

template <class Map, class Val> typename Map::const_iterator MapSearchByValue(const Map & SearchMap, const Val & SearchVal) 
{ 
    Map::const_iterator iRet = SearchMap.end(); 
    for (Map::const_iterator iTer = SearchMap.begin(); iTer != SearchMap.end(); iTer ++) 
    { 
     if (iTer->second == SearchVal) 
     { 
      iRet = iTer; 
      break; 
     } 
    } 
    return iRet; 
} 

मुझे लगता है कि यह उपयोगी है

+6

'std :: map :: खोज द्वारा कुंजी खोजें, वह मूल्य से खोज करने की कोशिश कर रहा है। – Dennis

+0

आप बिल्कुल सही हैं। मुझे लगता है कि हाथ से मानचित्र को फिर से ढूंढने और खोजने से कम, आपको पहले से सुझाए गए Boost.MultiIndex जैसे एक बिडरेक्शनल मानचित्र का उपयोग करना चाहिए। – Ternary

4

इस समारोह की कोशिश बहुत अच्छा विकल्प लेकिन कुछ मामलों में उपयोगी हो सकता है जहां उपयोगकर्ता इनिट पर 0 या एनयूएलएल जैसे डिफ़ॉल्ट मान निर्दिष्ट कर रहा है ialization।

Ex. 
< int , string > 
< string , int > 
< string , string > 

consider < string , string > 
mymap["1st"]="first"; 
mymap["second"]=""; 
for (std::map<string,string>::iterator it=mymap.begin(); it!=mymap.end(); ++it) 
{ 
     if (it->second =="") 
      continue; 
} 
+2

अगर मैं गलत हूं तो मुझे सही करें लेकिन क्या यह प्रश्न में सिर्फ कोड नहीं है? –

+2

@ जोनाथनमी आप गलत नहीं हैं। –

0

क्या आप अनुरोध कर रहे ठीक एक क्या std::find करता है (नहीं सदस्य समारोह)

template< class InputIt, class T > 
InputIt find(InputIt first, InputIt last, const T& value); 
0

नहीं है:

bool ContainsValue(Type_ value) 
{ 
    return (internalMap.find(value) != internalMap.end()); 
} 
संबंधित मुद्दे