निर्धारित करें कि क्या मानचित्र में किसी कुंजी का मान है?


256

यह निर्धारित करने का सबसे अच्छा तरीका क्या है कि एसटीएल के नक्शे में किसी दिए गए कुंजी का मूल्य है?

#include <map>

using namespace std;

struct Bar
{
    int i;
};

int main()
{
    map<int, Bar> m;
    Bar b = {0};
    Bar b1 = {1};

    m[0] = b;
    m[1] = b1;

    //Bar b2 = m[2];
    map<int, Bar>::iterator iter = m.find(2);
    Bar b3 = iter->second;

}

डीबगर में इसकी जांच करने पर ऐसा लगता है कि iterयह केवल कचरा डेटा है।

अगर मैं इस लाइन को अनकम्प्लीट करता हूँ:

Bar b2 = m[2]

डीबगर दिखाता है कि b2है {i = 0}। (मैं यह अनुमान लगा रहा हूं कि अपरिभाषित सूचकांक का उपयोग करने से सभी खाली / असिंचित मूल्यों के साथ एक संरचना वापस आ जाएगी)?

इनमें से कोई भी तरीका इतना बढ़िया नहीं है। मैं वास्तव में क्या पसंद करूँगा इस तरह का एक इंटरफ़ेस है:

bool getValue(int key, Bar& out)
{
    if (map contains value for key)
    {
        out = map[key];
        return true;
    }
    return false;
}

क्या इन रेखाओं के साथ कुछ मौजूद है?


2
डुप्लिकेट की कुंजी C ++ std :: map
OrangeDog

जवाबों:


274

क्या इन रेखाओं के साथ कुछ मौजूद है?

सं। Stl मैप क्लास के साथ, आप मैप ::find()को सर्च करने के लिए उपयोग करते हैं, और लौटे हुए इटरेटर की तुलना करते हैंstd::map::end()

इसलिए

map<int,Bar>::iterator it = m.find('2');
Bar b3;
if(it != m.end())
{
   //element found;
   b3 = it->second;
}

जाहिर है आप चाहें getValue()तो अपनी खुद की दिनचर्या लिख सकते हैं (सी ++ में भी, उपयोग करने का कोई कारण नहीं है out), लेकिन मुझे संदेह है कि एक बार जब आप का उपयोग करने का हैंग हो जाता है std::map::find()तो आप अपना समय बर्बाद नहीं करना चाहेंगे।

इसके अलावा आपका कोड थोड़ा गलत है:

m.find('2');एक कीवल्यू के लिए मानचित्र खोजेगा जो है '2'। IIRC C ++ संकलक '2' को एक इंट में बदल देगा, जिसके परिणामस्वरूप ASCII कोड '2' के लिए संख्यात्मक मान होता है जो कि आप नहीं चाहते हैं।

इस उदाहरण में आपकी कुंजीपट के बाद से intआप इस तरह की खोज करना चाहते हैं:m.find(2);


7
ऐसा कैसे? findइंगित करता है इरादे से बेहतर countहै। अधिक से अधिक, countआइटम वापस नहीं करता है। यदि आप ओपी के प्रश्न को पढ़ते हैं, तो वह अस्तित्व की जांच करना चाहता है, और तत्व को लौटाता है। findक्या वो। countनहीं करता।
एलन

अगर (m.count (कुंजी)) b3 = m [कुंजी]; // या जो भी
pconnell

61
मैं हमेशा इस बात के लिए उत्सुक रहा हूँ कि किस तरह का खरपतवार उन लोगों को धूम्रपान कर रहा था जिन्होंने पूरे stl API को डिज़ाइन किया था।
ट्रैप

2
एलन I को इस पर @dynamic से सहमत होना है, एक पुनरावृत्त को परिभाषित करना और फिर अंत के साथ तुलना करना यह कहने का एक स्वाभाविक तरीका नहीं है कि कुछ मौजूद नहीं है। यह कहना मेरे लिए कहीं अधिक सीधा है कि एक निश्चित तत्व इस नक्शे में कम से कम एक बार दिखाई देता है। जो गिनती करता है।
20

1
@ कलौड़ी सी ++ 20 बस इतना ही कहता है।
पूय 13

330

जब तक मानचित्र बहुपद नहीं है, तब तक सबसे सुंदर तरीकों में से एक गिनती पद्धति का उपयोग करना होगा

if (m.count(key))
    // key exists

गणना 1 होगी यदि तत्व वास्तव में नक्शे में मौजूद है।


22
क्या यह सभी कुंजियों की जांच नहीं करेगा , भले ही यह पहले से ही एक हो? यह महंगा उपवास कर सकता है ...
एमएमडानजाइगर

35
यह केवल एक कुंजी से अधिक की गणना करेगा यदि एक मल्टीपैप पर उपयोग किया जाता है।
एंड्रयू प्रोक

14
@mmdanziger नहीं, यह महंगा नहीं होगा: cplusplus.com/reference/map/map/count गणना आकार में लघुगणकीय है।
17:34 पर jgyou

28
कुंजी मौजूद है, और फिर क्या है? उस बिंदु पर आप आम तौर पर इसके लिए मूल्य प्राप्त करना चाहते हैं, किसी अन्य खोज के लिए भुगतान (उदाहरण के लिए operator[])। findआपको .NET का TryGetValueशब्दार्थ प्रदान करता है, जो लगभग हमेशा आप (और विशेष रूप से ओपी) चाहते हैं।
ओहद श्नाइडर

2
@serine समझ गए। ध्यान दें कि जारी करने में कुंजी गायब होने पर व्यवहार भिन्न होगा, क्योंकि मानचित्र [कुंजी] एक नए डिफ़ॉल्ट-निर्मित तत्व मान को लौटाएगा।
ओहद श्नाइडर

53

यह पहले से ही मौजूद है केवल सटीक सिंटैक्स में नहीं।

if (m.find(2) == m.end() )
{
    // key 2 doesn't exist
}

यदि आप मान का उपयोग करना चाहते हैं यदि यह मौजूद है, तो आप कर सकते हैं:

map<int, Bar>::iterator iter = m.find(2);
if (iter != m.end() )
{
    // key 2 exists, do something with iter->second (the value)
}

C ++ 0x और ऑटो के साथ, सिंटैक्स सरल है:

auto iter = m.find(2);
if (iter != m.end() )
{
    // key 2 exists, do something with iter->second (the value)
}

मेरा सुझाव है कि आप इसे सरल बनाने के लिए एक नए तंत्र के साथ आने की कोशिश करने के बजाय इसकी आदत डालें। आप कोड को थोड़ा कम करने में सक्षम हो सकते हैं, लेकिन ऐसा करने की लागत पर विचार करें। अब आपने एक नया कार्य आरंभ किया है जिसे C ++ से परिचित लोग पहचान नहीं पाएंगे।

यदि आप इन चेतावनियों के बावजूद इसे लागू करना चाहते हैं, तो:

template <class Key, class Value, class Comparator, class Alloc>
bool getValue(const std::map<Key, Value, Comparator, Alloc>& my_map, int key, Value& out)
{
    typename std::map<Key, Value, Comparator, Alloc>::const_iterator it = my_map.find(key);
    if (it != my_map.end() )
    {
        out = it->second;
        return true;
    }
    return false;
}

38

मैंने अभी देखा कि C ++ 20 के साथ , हमारे पास होगा

bool std::map::contains( const Key& key ) const;

यदि मानचित्र कुंजी के साथ एक तत्व रखता है तो यह सही होगा key


अंत में एक जवाब जो इस फ़ंक्शन के बारे में बात करता है! (C ++ 20)
सैमुअल रसकिन्हा

आखिरकार ? धन्यवाद, लेकिन यह लगभग 2 साल पुराना है! ;-)
kebs

7

amap.findरिटर्न amap::endजब यह आप के लिए क्या देख रहे हैं नहीं मिल रहा है - आपको लगता है कि जांच करने के लिए माना जाता कर रहे हैं।


4

के findखिलाफ वापसी मूल्य की जाँच करें end

map<int, Bar>::iterator it = m.find('2');
if ( m.end() != it ) { 
  // contains
  ...
}

1

आप निम्न कोड के साथ अपना getValue फ़ंक्शन बना सकते हैं:

bool getValue(const std::map<int, Bar>& input, int key, Bar& out)
{
   std::map<int, Bar>::iterator foundIter = input.find(key);
   if (foundIter != input.end())
   {
      out = foundIter->second;
      return true;
   }
   return false;
}

मेरा मानना ​​है कि लाइन 6 होना चाहिएout = foundIter->second
डिथर्मैस्टर

मैंने किप के जवाब को ठीक से दिखाने के out = foundIter->secondबजाय तय कियाout = *foundIter
नेटजेफ

1

कुछ अन्य उत्तरों को संक्षेप में संक्षेप में प्रस्तुत करने के लिए:

यदि आप अभी तक C ++ 20 का उपयोग नहीं कर रहे हैं, तो आप अपना स्वयं का mapContainsKeyफ़ंक्शन लिख सकते हैं :

bool mapContainsKey(std::map<int, int>& map, int key)
{
  if (map.find(key) == map.end()) return false;
  return true;
}

यदि आप mapबनाम unordered_mapऔर विभिन्न कुंजी और मूल्य प्रकारों के लिए कई अतिभार से बचना चाहते हैं , तो आप इसे एक templateफ़ंक्शन बना सकते हैं ।

यदि आप उपयोग कर रहे हैं C++ 20या बाद में, एक अंतर्निहित containsकार्य होगा:

std::map<int, int> myMap;

// do stuff with myMap here

int key = 123;

if (myMap.contains(key))
{
  // stuff here
}

-1

यदि आप यह निर्धारित करना चाहते हैं कि मानचित्र में कोई कुंजी है या नहीं, तो आप मानचित्र के खोज () या गिनती () सदस्य फ़ंक्शन का उपयोग कर सकते हैं। खोज फ़ंक्शन जिसका उपयोग यहां किया गया है उदाहरण में तत्व या मानचित्र पर पुनरावृत्ति देता है :: अन्यथा समाप्त। गणना के मामले में, यदि रिटर्न 1 मिलता है, तो यह शून्य (या अन्यथा) देता है।

if(phone.count(key))
{ //key found
}
else
{//key not found
}

for(int i=0;i<v.size();i++){
    phoneMap::iterator itr=phone.find(v[i]);//I have used a vector in this example to check through map you cal receive a value using at() e.g: map.at(key);
    if(itr!=phone.end())
        cout<<v[i]<<"="<<itr->second<<endl;
    else
        cout<<"Not found"<<endl;
}

-1

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

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;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.