खोज विधि का उपयोग करने के बाद std :: map को कैसे अपडेट करें?


90

How to update the value of a key in std::map after using the find method?

I have a map and iterator declaration like this:

map <char, int> m1;
map <char, int>::iterator m1_it;
typedef pair <char, int> count_pair;

I'm using the map to store the number of occurrences of a character.

I'm using Visual C++ 2010.

जवाबों:


130

std::map::findपाया तत्व के लिए एक पुनरावृत्ति देता है (या end()यदि तत्व नहीं मिला था)। जब तक mapकास्ट नहीं है, तब तक आप पुनरावृत्त द्वारा बताए गए तत्व को संशोधित कर सकते हैं:

std::map<char, int> m;
m.insert(std::make_pair('c', 0));  // c is for cookie

std::map<char, int>::iterator it = m.find('c'); 
if (it != m.end())
    it->second = 42;

2
धन्यवाद। क्या [] ऑपरेटर का उपयोग करना भी संभव है?
जयकुमार

1
@ जय: हाँ, लेकिन व्यवहार अलग है। देखें प्रलेखन द्वारा प्रदान की विभिन्न कार्यों के लिए । mapmap
जेम्स मैकनेलिस

3
मुझे मिला error: assignment of member 'std::pair<char* const, char*>::second' in read-only object:(
टॉम ब्रिटो

1
@ संजयकुमार मुझे लगता है कि हां, लेकिन इस समाधान का नुकसान यह है कि, मानचित्र को दूसरी बार आइटम का स्थान ढूंढना होगा (पहली बार आपकी खोज विधि का कॉल है) जो लॉग (एन) जटिलता के साथ ऑपरेशन है। यह एक ही ऑपरेशन का दोहराव है।
सत्यसेकर

51

मैं ऑपरेटर [] का उपयोग करेगा।

map <char, int> m1;

m1['G'] ++;  // If the element 'G' does not exist then it is created and 
             // initialized to zero. A reference to the internal value
             // is returned. so that the ++ operator can be applied.

// If 'G' did not exist it now exist and is 1.
// If 'G' had a value of 'n' it now has a value of 'n+1'

इसलिए इस तकनीक का उपयोग करके सभी पात्रों को एक स्ट्रीम से पढ़ना और उनकी गिनती करना वास्तव में आसान हो जाता है:

map <char, int>                m1;
std::ifstream                  file("Plop");
std::istreambuf_iterator<char> end;

for(std::istreambuf_iterator<char> loop(file); loop != end; ++loop)
{
    ++m1[*loop]; // prefer prefix increment out of habbit
}

3
आपका उत्तर वास्तविक प्रश्न के लिए बहुत अच्छा है - दुख की बात यह है कि पूछने वाला चूक गया (और इसलिए इसे) एक स्पष्ट तरीके से स्वीकार करता है। इसलिए मुझे लगता है कि इस तथ्य के बारे में एक छोटा बयान देना और भी बेहतर होगा: जो लोग बहुत तेजी से "पढ़ते हैं", []उनका मानना ​​है कि आप उपयोग करने के बाद उपयोग करने का सुझाव दे रहे हैं find(मुझे नहीं लगता कि यह आपका इरादा था)।
वुल्फ

ठीक है, मुझे लगता है कि अगर कोई तत्व सम्मिलित रूप से सम्मिलित नहीं करना चाहता है तो 'खोज' बेहतर हो सकता है । SIGSEGV द्वारा 'खोजने' और मरने को प्राथमिकता दी जा सकती है।
ग्वांगमु ली

1
@GwangmuLee डी-रेफ़ररेटर end()अपरिभाषित व्यवहार अपरिभाषित है, इसे उत्पन्न करने की आवश्यकता नहीं है SIGSEGV(और मेरे अनुभव में ऐसा करने की संभावना नहीं है)।
मार्टिन

5

आप std::map::atसदस्य फ़ंक्शन का उपयोग कर सकते हैं , यह कुंजी k के साथ पहचाने गए तत्व के मैप किए गए मान का संदर्भ देता है।

std::map<char,int> mymap = {
                               { 'a', 0 },
                               { 'b', 0 },
                           };

  mymap.at('a') = 10;
  mymap.at('b') = 20;

1

यदि आप पहले से ही कुंजी जानते हैं, तो आप सीधे उस कुंजी का उपयोग करके मूल्य को अपडेट कर सकते हैं m[key] = new_value

यहाँ एक नमूना कोड है जो मदद कर सकता है:

map<int, int> m;

for(int i=0; i<5; i++)
    m[i] = i;

for(auto it=m.begin(); it!=m.end(); it++)
    cout<<it->second<<" ";
//Output: 0 1 2 3 4

m[4] = 7;  //updating value at key 4 here

cout<<"\n"; //Change line

for(auto it=m.begin(); it!=m.end(); it++)
    cout<<it->second<<" ";
// Output: 0 1 2 3 7    

0

आप भी कर सकते हैं ऐसा-

 std::map<char, int>::iterator it = m.find('c'); 
 if (it != m.end())
 (*it).second = 42;

0

आप निम्न की तरह मान को अपडेट कर सकते हैं

   auto itr = m.find('ch'); 
     if (itr != m.end()){
           (*itr).second = 98;
     }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.