Find metodunu kullandıktan sonra std :: map nasıl güncellenir?


92

Yöntemi std::mapkullandıktan sonra bir anahtarın değeri nasıl güncellenir find?

Bunun gibi bir harita ve yineleyici bildirimim var:

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

Bir karakterin oluşum sayısını saklamak için haritayı kullanıyorum.

Visual C ++ 2010 kullanıyorum.

Yanıtlar:


133

std::map::findbulunan öğeye (veya end()öğe bulunmadıysa) bir yineleyici döndürür . mapConst olmadığı sürece , yineleyici tarafından işaret edilen öğeyi değiştirebilirsiniz:

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
Teşekkürler. [] Operatörünü kullanmak da mümkün mü?
jaykumarark

1
@Jay: Evet, ama davranış farklı. Tarafından sağlanan çeşitli işlevler için mapbelgelere bakın map.
James McNellis

3
Bende error: assignment of member 'std::pair<char* const, char*>::second' in read-only object:(
Tom Brito

1
@jaykumarark Evet diye düşünüyorum, ancak bu çözümün dezavantajı, haritanın nesnenin yerini ikinci kez bulması gerektiğidir (ilk sefer sizin bulma yönteminizdir), bu da log (N) karmaşıklığı ile işlemdir. Aynı işlemin gereksiz tekrarıdır.
truthseeker

52

[] Operatörünü kullanırdım.

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'

Dolayısıyla, bu tekniği kullanarak bir akıştaki tüm karakterleri okumak ve saymak gerçekten kolay hale gelir:

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
Cevabınız asıl soru için harikadır - ne yazık ki soruyu soran kişi bunu açıkça sormayı (ve dolayısıyla kabul etmeyi) kaçırmıştır. Bu nedenle, bu gerçek hakkında kısa bir açıklama yapmanın daha da iyi olacağını düşünüyorum: çok hızlı "okuyan" insanlar, kullandıktan []sonra kullanmayı önerdiğinizi finddüşünebilirler (niyetinin bu olduğunu sanmıyorum).
Wolf

Bence 'bul', örtük olarak bir öğe eklemek istemiyorsa daha iyi olabilir . SIGSEGV tarafından 'bulmayı' iptal etmek ve ölmek tercih edilebilir.
Gwangmu Lee

1
@GwangmuLee end()Yineleyicinin referansının kaldırılması , tanımlanmamış bir davranıştır, bunun bir oluşturması gerekmez SIGSEGV(ve benim deneyimlerime göre bunu yapma olasılığı düşüktür).
Martin York

5

std::map::atÜye fonksiyonunu kullanabilirsiniz , k tuşu ile tanımlanan elemanın eşlenmiş değerine bir referans döndürür.

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

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

1

Anahtarı zaten biliyorsanız, bu anahtardaki değeri doğrudan güncelleyebilirsiniz. m[key] = new_value

İşte yardımcı olabilecek örnek bir kod:

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

Bunu da yapabilirsiniz-

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

0

Değeri aşağıdaki gibi güncelleyebilirsiniz

   auto itr = m.find('ch'); 
     if (itr != m.end()){
           (*itr).second = 98;
     }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.