खोज…


टिप्पणियों

  • किसी भी std::map या std::multimap शीर्षक फ़ाइल का उपयोग करने के लिए <map> शामिल होना चाहिए।

  • std::map and std::multimap दोनों अपने तत्वों को कुंजी के आरोही क्रम के अनुसार क्रमबद्ध रखते हैं। std::multimap मामले में, समान कुंजी के मानों के लिए कोई छँटाई नहीं होती है।

  • std::map और std::multimap बीच मूल अंतर यह है कि std::map एक ही कुंजी के लिए डुप्लिकेट मान की अनुमति नहीं देता है जहाँ std::multimap करता है।

  • नक्शे को बाइनरी सर्च ट्री के रूप में लागू किया जाता है। इसलिए औसत में search() , insert() , erase() एन (लॉग एन) समय लेता है। निरंतर समय संचालन के लिए std::unordered_map उपयोग करें।

  • size() और empty() फ़ंक्शन में Θ (1) समय की जटिलता है, नोड्स की संख्या को हर बार पेड़ से चलने से बचने के लिए कैश किया जाता है, जब ये फ़ंक्शन कहलाते हैं।

तत्वों तक पहुंचना

एक std::map इनपुट के रूप में (key, value) जोड़े लेता है।

निम्न उदाहरण पर विचार करें std::map आरंभीकरण:

std::map < std::string, int > ranking { std::make_pair("stackoverflow", 2), 
                                        std::make_pair("docs-beta", 1) };

एक std::map , तत्वों को इस प्रकार डाला जा सकता है:

ranking["stackoverflow"]=2;
ranking["docs-beta"]=1;

उपरोक्त उदाहरण में, यदि कुंजी stackoverflow पहले से मौजूद है, तो इसका मान 2 में अपडेट किया जाएगा। यदि यह पहले से मौजूद नहीं है, तो एक नई प्रविष्टि बनाई जाएगी।

एक std::map , तत्वों को एक इंडेक्स के रूप में कुंजी देकर सीधे एक्सेस किया जा सकता है:

std::cout << ranking[ "stackoverflow" ] << std::endl;

मानचित्र पर operator[] का उपयोग करते हुए ध्यान दें कि वास्तव में नक्शे में queried कुंजी के साथ एक नया मूल्य सम्मिलित करेगा। इसका मतलब यह है कि आप इसे एक const std::map पर उपयोग नहीं कर सकते हैं, भले ही वह की पहले से ही मैप में स्टोर हो। इस प्रविष्टि को रोकने के लिए, जाँच करें कि क्या तत्व मौजूद है (उदाहरण के लिए find() का उपयोग करके) या नीचे दिए गए अनुसार at() उपयोग करें।

सी ++ 11

एक std::map तत्व std::map at() साथ पहुँचा जा सकता है:

std::cout << ranking.at("stackoverflow") << std::endl;

ध्यान दें कि at() एक std::out_of_range फेंक देगा std::out_of_range अपवाद यदि कंटेनर में अनुरोधित तत्व नहीं है।

दोनों कंटेनरों में std::map and std::multimap , तत्वों का उपयोग करके इसे एक्सेस किया जा सकता है:

सी ++ 11
// Example using begin()
std::multimap < int, std::string > mmp { std::make_pair(2, "stackoverflow"),
                                         std::make_pair(1, "docs-beta"),
                                         std::make_pair(2, "stackexchange")  };
auto it = mmp.begin();
std::cout << it->first << " : " << it->second << std::endl; // Output: "1 : docs-beta"
it++;
std::cout << it->first << " : " << it->second << std::endl; // Output: "2 : stackoverflow"
it++;
std::cout << it->first << " : " << it->second << std::endl; // Output: "2 : stackexchange"

// Example using rbegin()
std::map < int, std::string > mp {  std::make_pair(2, "stackoverflow"),
                                    std::make_pair(1, "docs-beta"),
                                    std::make_pair(2, "stackexchange")  };
auto it2 = mp.rbegin();
std::cout << it2->first << " : " << it2->second << std::endl; // Output: "2 : stackoverflow"
it2++;
std::cout << it2->first << " : " << it2->second << std::endl; // Output: "1 : docs-beta"

एक std :: मैप या std :: मल्टीपैप को इनिशियलाइज़ करना

std::map और std::multimap दोनों को कॉमा द्वारा अलग किए गए कुंजी-मूल्य जोड़े प्रदान करके आरंभ किया जा सकता है। कुंजी-मूल्य जोड़े या तो {key, value} द्वारा प्रदान किए जा सकते हैं या std::make_pair(key, value) द्वारा स्पष्ट रूप से बनाए जा सकते हैं। जैसा कि std::map डुप्लिकेट कुंजियों की अनुमति नहीं देता है और अल्पविराम ऑपरेटर बाएं से दाएं प्रदर्शन करता है, दाईं ओर की जोड़ी बाईं ओर समान कुंजी के साथ जोड़ी के साथ ओवरराइट की जाएगी।

std::multimap < int, std::string > mmp { std::make_pair(2, "stackoverflow"),
                                     std::make_pair(1, "docs-beta"),
                                     std::make_pair(2, "stackexchange")  };
// 1 docs-beta
// 2 stackoverflow
// 2 stackexchange

std::map < int, std::string > mp {  std::make_pair(2, "stackoverflow"),
                                std::make_pair(1, "docs-beta"),
                                std::make_pair(2, "stackexchange")  }; 
// 1 docs-beta
// 2 stackoverflow

दोनों को पुनरावृत्ति के साथ आरंभ किया जा सकता है।

// From std::map or std::multimap iterator
std::multimap< int , int > mmp{ {1, 2}, {3, 4}, {6, 5}, {8, 9}, {6, 8}, {3, 4}, 
                               {6, 7} };
                       // {1, 2}, {3, 4}, {3, 4}, {6, 5}, {6, 8}, {6, 7}, {8, 9}
auto it = mmp.begin();
std::advance(it,3); //moved cursor on first {6, 5}
std::map< int, int > mp(it, mmp.end()); // {6, 5}, {8, 9}

//From std::pair array
std::pair< int, int > arr[10];
arr[0] = {1, 3};
arr[1] = {1, 5};
arr[2] = {2, 5};
arr[3] = {0, 1};
std::map< int, int > mp(arr,arr+4); //{0 , 1}, {1, 3}, {2, 5}

//From std::vector of std::pair
std::vector< std::pair<int, int> > v{ {1, 5}, {5, 1}, {3, 6}, {3, 2} };
std::multimap< int, int > mp(v.begin(), v.end()); 
                        // {1, 5}, {3, 6}, {3, 2}, {5, 1}

तत्वों को हटाना

सभी तत्वों को हटाना:

std::multimap< int , int > mmp{ {1, 2}, {3, 4}, {6, 5}, {8, 9}, {3, 4}, {6, 7} };
mmp.clear(); //empty multimap

तत्व की मदद से कहीं से तत्व निकालना:

std::multimap< int , int > mmp{ {1, 2}, {3, 4}, {6, 5}, {8, 9}, {3, 4}, {6, 7} };
                            // {1, 2}, {3, 4}, {3, 4}, {6, 5}, {6, 7}, {8, 9}
auto it = mmp.begin();
std::advance(it,3); // moved cursor on first {6, 5}
mmp.erase(it); // {1, 2}, {3, 4}, {3, 4}, {6, 7}, {8, 9}

सभी तत्वों को एक सीमा में निकालना:

std::multimap< int , int > mmp{ {1, 2}, {3, 4}, {6, 5}, {8, 9}, {3, 4}, {6, 7} };
                            // {1, 2}, {3, 4}, {3, 4}, {6, 5}, {6, 7}, {8, 9}
auto it = mmp.begin();
auto it2 = it;
it++; //moved first cursor on first {3, 4}
std::advance(it2,3);  //moved second cursor on first {6, 5}
mmp.erase(it,it2); // {1, 2}, {6, 5}, {6, 7}, {8, 9}

कुंजी के रूप में प्रदान किए गए सभी तत्वों को हटाना:

std::multimap< int , int > mmp{ {1, 2}, {3, 4}, {6, 5}, {8, 9}, {3, 4}, {6, 7} };
                            // {1, 2}, {3, 4}, {3, 4}, {6, 5}, {6, 7}, {8, 9}
mmp.erase(6); // {1, 2}, {3, 4}, {3, 4}, {8, 9}

उन तत्वों को हटाना जो एक विधेय pred संतुष्ट करते हैं:

std::map<int,int> m;
auto it = m.begin();
while (it != m.end())
{
   if (pred(*it))
       it = m.erase(it);
   else
       ++it;
}

तत्वों को सम्मिलित करना

एक तत्व को एक std::map तभी डाला जा सकता है, जब उसकी कुंजी मैप में पहले से मौजूद न हो। उदाहरण के लिए दिया गया:

std::map< std::string, size_t > fruits_count;
  • एक कुंजी-मूल्य जोड़ी को एक सम्मिलित std::map में insert() सदस्य फ़ंक्शन के माध्यम से डाला जाता है। इसके लिए एक तर्क के रूप में एक pair आवश्यकता होती है:

    fruits_count.insert({"grapes", 20});
    fruits_count.insert(make_pair("orange", 30));
    fruits_count.insert(pair<std::string, size_t>("banana", 40));
    fruits_count.insert(map<std::string, size_t>::value_type("cherry", 50));
    

    insert() फ़ंक्शन एक pair को पुनरावृत्त और एक bool मान से bool :

    • यदि सम्मिलन सफल रहा, तो पुनरावृत्त नव सम्मिलित तत्व को इंगित करता है, और bool मान true
    • यदि पहले से ही एक ही key साथ एक तत्व था, तो सम्मिलन विफल रहता है। जब ऐसा होता है, तो इट्रेटर तत्व को संघर्ष का कारण बताता है, और bool मान false

    प्रविष्टि और खोज ऑपरेशन को संयोजित करने के लिए निम्न विधि का उपयोग किया जा सकता है:

    auto success = fruits_count.insert({"grapes", 20});
    if (!success.second) {           // we already have 'grapes' in the map
        success.first->second += 20; // access the iterator to update the value
    }
    
  • सुविधा के लिए, std::map कंटेनर, सबस्क्रिप्ट ऑपरेटर को मानचित्र में तत्वों तक पहुँचने के लिए और यदि वे मौजूद नहीं हैं तो नए को सम्मिलित करने के लिए प्रदान करते हैं:

    fruits_count["apple"] = 10;
    

    सरल होते हुए, यह उपयोगकर्ता को यह जाँचने से रोकता है कि क्या तत्व पहले से मौजूद है। यदि कोई तत्व अनुपलब्ध है, तो std::map::operator[] अंतर्निहित रूप से इसे बनाता है, इसे आपूर्ति किए गए मान के साथ अधिलेखित करने से पहले डिफ़ॉल्ट निर्माणकर्ता के साथ प्रारंभ करता है।

  • insert() का उपयोग एक साथ कई तत्वों को जोड़ने के लिए किया जा सकता है जब एक जोड़े की लट सूची का उपयोग किया जाता है। डालने का यह संस्करण () शून्य देता है:

    fruits_count.insert({{"apricot", 1}, {"jackfruit", 1}, {"lime", 1}, {"mango", 7}}); 
    
  • insert() का उपयोग तत्वों को जोड़ने के लिए किया जा सकता है, जो value_type का उपयोग करके value_type मानों के आरंभ और अंत को value_type हैं:

    std::map< std::string, size_t > fruit_list{ {"lemon", 0}, {"olive", 0}, {"plum", 0}};
    fruits_count.insert(fruit_list.begin(), fruit_list.end()); 
    

उदाहरण:

std::map<std::string, size_t> fruits_count;
std::string fruit;
while(std::cin >> fruit){
    // insert an element with 'fruit' as key and '1' as value
    // (if the key is already stored in fruits_count, insert does nothing)
    auto ret = fruits_count.insert({fruit, 1});
    if(!ret.second){            // 'fruit' is already in the map 
        ++ret.first->second;    // increment the counter
    }
}

एक सम्मिलन ऑपरेशन के लिए समय जटिलता हे (लॉग एन) है क्योंकि std::map पेड़ों के रूप में लागू किया जाता है।

सी ++ 11

एक pair का निर्माण स्पष्ट रूप से make_pair() और emplace() का उपयोग करके किया जा सकता है:

std::map< std::string , int > runs;
runs.emplace("Babe Ruth", 714);
runs.insert(make_pair("Barry Bonds", 762));

हम जानते हैं कि जहां नए तत्व सम्मिलित किया जाएगा, तो हम उपयोग कर सकते हैं emplace_hint() पुनरावर्तक निर्दिष्ट करने के लिए hint । यदि नए तत्व को hint से ठीक पहले डाला जा सकता है, तो निरंतर समय में सम्मिलन किया जा सकता है। अन्यथा यह उसी तरह से व्यवहार करता है जैसे कि emplace() :

std::map< std::string , int > runs;
auto it = runs.emplace("Barry Bonds", 762); // get iterator to the inserted element
// the next element will be before "Barry Bonds", so it is inserted before 'it'
runs.emplace_hint(it, "Babe Ruth", 714);

एसटीडी पर नक्शा :: नक्शा या एसटीडी :: मल्टीमैप

std::map या std::multimap निम्नलिखित तरीकों से पता std::multimap जा सकता है:

std::multimap< int , int > mmp{ {1, 2}, {3, 4}, {6, 5}, {8, 9}, {3, 4}, {6, 7} };
                               
//Range based loop - since C++11
for(const auto &x: mmp) 
    std::cout<< x.first <<":"<< x.second << std::endl;

//Forward iterator for loop: it would loop through first element to last element
//it will be a std::map< int, int >::iterator
for (auto it = mmp.begin(); it != mmp.end(); ++it)
std::cout<< it->first <<":"<< it->second << std::endl; //Do something with iterator

//Backward iterator for loop: it would loop through last element to first element
//it will be a std::map< int, int >::reverse_iterator
for (auto it = mmp.rbegin(); it != mmp.rend(); ++it)
std::cout<< it->first <<" "<< it->second << std::endl; //Do something with iterator

एक std::map या एक std::multimap पर पुनरावृति करते समय, बेकार निहित रूपांतरण से बचने के लिए auto का उपयोग पसंद किया जाता है (अधिक विवरण के लिए यह SO उत्तर देखें)।

एसटीडी में खोज :: नक्शा या एसटीडी में :: मल्टीमैप

std::map या std::multimap में कुंजी खोजने के कई तरीके हैं।

  • कुंजी की पहली घटना का पुनरावृत्ति प्राप्त करने के लिए, find() फ़ंक्शन का उपयोग किया जा सकता है। यदि कुंजी मौजूद नहीं है तो यह end() देता है।

      std::multimap< int , int > mmp{ {1, 2}, {3, 4}, {6, 5}, {8, 9}, {3, 4}, {6, 7} };
      auto it = mmp.find(6);
      if(it!=mmp.end())
          std::cout << it->first << ", " << it->second << std::endl; //prints: 6, 5
      else
          std::cout << "Value does not exist!" << std::endl;
    
      it = mmp.find(66);
      if(it!=mmp.end())
          std::cout << it->first << ", " << it->second << std::endl; 
      else
          std::cout << "Value does not exist!" << std::endl; // This line would be executed.
    
  • यह पता लगाने का एक और तरीका है कि क्या कोई प्रविष्टि std::map या std::map में मौजूद है std::multimap count() फ़ंक्शन का उपयोग कर रहा है, जो यह बताता है कि किसी दिए गए कुंजी के साथ कितने मान जुड़े हैं। चूंकि std::map प्रत्येक कुंजी के साथ केवल एक मान को जोड़ता है, इसकी count() फ़ंक्शन केवल 0 (यदि कुंजी मौजूद नहीं है) या 1 (यदि यह है) वापस कर सकता है। std::multimap , count() 1 से अधिक मान लौटा सकते हैं क्योंकि एक ही कुंजी से जुड़े कई मान हो सकते हैं।

     std::map< int , int > mp{ {1, 2}, {3, 4}, {6, 5}, {8, 9}, {3, 4}, {6, 7} };
     if(mp.count(3) > 0) // 3 exists as a key in map
         std::cout << "The key exists!" << std::endl; // This line would be executed.
     else
         std::cout << "The key does not exist!" << std::endl;
    

    आप केवल परवाह कुछ तत्व मौजूद है या नहीं, तो find के लिए अपने इरादे और, के लिए यह दस्तावेज: सख्ती से बेहतर है multimaps , यह एक बार पहले मिलान तत्व पाया गया है रोक सकता है।

  • std::multimap के मामले में, एक ही कुंजी वाले कई तत्व हो सकते हैं। इस श्रेणी को प्राप्त करने के लिए, equal_range() फ़ंक्शन का उपयोग किया जाता है, जो क्रमशः std::pair को निम्नतर बाउंड (सम्मिलित) और ऊपरी बाउंड (अनन्य) देता है। यदि कुंजी मौजूद नहीं है, तो दोनों पुनरावृत्तियों को end() करने के लिए इंगित करेंगे end()

      auto eqr = mmp.equal_range(6);
      auto st = eqr.first, en = eqr.second;
      for(auto it = st; it != en; ++it){
          std::cout << it->first << ", " << it->second << std::endl; 
      }
          // prints: 6, 5
          //         6, 7
    

तत्वों की संख्या की जाँच

कंटेनर std::map में एक सदस्य फ़ंक्शन empty() , जो true या false , यह निर्भर करता है कि नक्शा खाली है या नहीं। सदस्य फ़ंक्शन size() एक std::map में संग्रहीत तत्व की संख्या देता है std::map कंटेनर:

std::map<std::string , int> rank {{"facebook.com", 1} ,{"google.com", 2}, {"youtube.com", 3}};
if(!rank.empty()){
    std::cout << "Number of elements in the rank map: " << rank.size() << std::endl;
}
else{
    std::cout << "The rank map is empty" << std::endl;
}

नक्शे के प्रकार

नियमित मानचित्र

नक्शा एक सहयोगी कंटेनर है, जिसमें कुंजी-मूल्य जोड़े हैं।

#include <string>
#include <map>
std::map<std::string, size_t> fruits_count;

उपरोक्त उदाहरण में, std::string प्रमुख प्रकार है, और size_t एक मान है

मुख्य नक्शे में एक सूचकांक के रूप में कार्य करता है। प्रत्येक कुंजी अद्वितीय होनी चाहिए, और आदेशित होनी चाहिए।

  • यदि आपको एक ही कुंजी के साथ multimap तत्वों की आवश्यकता है, तो multimap का उपयोग करने पर विचार करें (नीचे समझाया गया है)

  • यदि आपका मूल्य प्रकार कोई आदेश निर्दिष्ट नहीं करता है, या आप डिफ़ॉल्ट आदेश को ओवरराइड करना चाहते हैं, तो आप एक प्रदान कर सकते हैं:

    #include <string>
    #include <map>
    #include <cstring>
    struct StrLess {
        bool operator()(const std::string& a, const std::string& b) {
            return strncmp(a.c_str(), b.c_str(), 8)<0;
                   //compare only up to 8 first characters
        }
    }
    std::map<std::string, size_t, StrLess> fruits_count2;
    

    यदि StrLess तुलनित्र दो कुंजी के लिए false , तो उन्हें समान माना जाता है, भले ही उनकी वास्तविक सामग्री अलग हो।

मल्टी मानचित्र

मल्टीमैप एक ही कुंजी के साथ कई कुंजी-मूल्य जोड़े को मानचित्र में संग्रहीत करने की अनुमति देता है। अन्यथा, इसका इंटरफ़ेस और निर्माण नियमित मानचित्र के समान है।

 #include <string>
 #include <map>
 std::multimap<std::string, size_t> fruits_count;
 std::multimap<std::string, size_t, StrLess> fruits_count2;

हैश-मैप (अनियंत्रित मानचित्र)

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

#include <string>
#include <unordered_map>
std::unordered_map<std::string, size_t> fruits_count;

अनियंत्रित नक्शे आमतौर पर तेज़ होते हैं, लेकिन तत्व किसी भी अनुमानित क्रम में संग्रहीत नहीं होते हैं। उदाहरण के लिए, एक unordered_map में सभी तत्वों से अधिक पुनरावृति तत्वों को एक प्रतीत होता है यादृच्छिक क्रम में देता है।

कुंजी के रूप में उपयोगकर्ता परिभाषित प्रकार के साथ एसटीडी :: नक्शा बनाना

किसी मानचित्र में कुंजी के रूप में एक वर्ग का उपयोग करने में सक्षम होने के लिए, कुंजी की आवश्यकता होती है, यह सब copiable और assignable । मानचित्र के भीतर आदेश को तीसरे तर्क द्वारा टेम्पलेट में परिभाषित किया गया है (और यदि उपयोग किया जाता है, तो तर्क निर्माता के लिए)। यह डिफॉल्ट्स को std::less<KeyType> , जो डिफॉल्ट करता है < ऑपरेटर, लेकिन डिफॉल्ट्स का उपयोग करने की कोई आवश्यकता नहीं है। बस एक तुलना ऑपरेटर (अधिमानतः एक कार्यात्मक वस्तु के रूप में) लिखें:

struct CmpMyType
{
    bool operator()( MyType const& lhs, MyType const& rhs ) const
    {
        //  ...
    }
};

सी ++ में, "तुलना" विधेय एक सख्त कमजोर आदेश होना चाहिए। विशेष रूप से, compare(X,X) किसी भी X लिए false लौटना चाहिए। यानी अगर CmpMyType()(a, b) सही लौटाता है, तो CmpMyType()(b, a) को गलत लौटना चाहिए, और यदि दोनों गलत हैं, तो तत्वों को समान माना जाता है (समान समतुल्य वर्ग के सदस्य)।

सख्त कमजोर आदेश

यह दो वस्तुओं के बीच संबंध को परिभाषित करने के लिए एक गणितीय शब्द है।
इसकी परिभाषा है:

दो वस्तुएं x और y समतुल्य हैं यदि f (x, y) और f (y, x) दोनों गलत हैं। ध्यान दें कि एक वस्तु हमेशा (अपने आप के समतुल्य अपरिवर्तनीयता द्वारा) होती है।

C ++ के संदर्भ में इसका मतलब है कि यदि आपके पास दिए गए प्रकार की दो वस्तुएं हैं, तो आपको ऑपरेटर के साथ तुलना करते समय निम्नलिखित मान वापस करने चाहिए।

X    a;
X    b;

Condition:                  Test:     Result
a is equivalent to b:       a < b     false
a is equivalent to b        b < a     false

a is less than b            a < b     true
a is less than b            b < a     false

b is less than a            a < b     false
b is less than a            b < a     true

आप किस प्रकार समकक्ष / कम परिभाषित करते हैं, यह पूरी तरह से आपकी वस्तु के प्रकार पर निर्भर करता है।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow