Bagaimana cara memperbarui std :: map setelah menggunakan metode find?

90

Bagaimana cara memperbarui nilai kunci std::mapsetelah menggunakan findmetode ini?

Saya memiliki peta dan deklarasi iterator seperti ini:

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

Saya menggunakan peta untuk menyimpan jumlah kemunculan karakter.

Saya menggunakan Visual C ++ 2010.

jaykumarark
sumber

Jawaban:

130

std::map::findmengembalikan iterator ke elemen yang ditemukan (atau ke end()jika elemen tidak ditemukan). Selama mapis not const, Anda dapat memodifikasi elemen yang ditunjuk oleh iterator:

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;
James McNellis
sumber
2
Terima kasih. Apakah mungkin juga menggunakan operator []?
jaykumarark
1
@ Jay: Ya, tapi perilakunya berbeda. Lihat yang mapdokumentasi untuk berbagai fungsi yang disediakan oleh map.
James McNellis
3
Saya mendapat error: assignment of member 'std::pair<char* const, char*>::second' in read-only object:(
Tom Brito
1
@jaykumarark Saya rasa ya, tapi kekurangan dari solusi ini adalah, map harus menemukan lokasi item untuk kedua kalinya (pertama kali adalah panggilan metode find) yang dioperasikan dengan kompleksitas log (N). Ini adalah duplikasi yang tidak perlu dari operasi yang sama.
pencari kebenaran
51

Saya akan menggunakan operator [].

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'

Jadi dengan menggunakan teknik ini, menjadi sangat mudah untuk membaca semua karakter dari aliran dan menghitungnya:

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
}
Martin York
sumber
3
Jawaban Anda bagus untuk pertanyaan yang sebenarnya - sayangnya penanya tidak menjawab (dan karenanya menerima) ini dengan cara yang jelas. Itulah mengapa saya pikir akan lebih baik untuk memberikan pernyataan singkat tentang fakta ini: orang yang "membaca" dengan sangat cepat, mungkin percaya bahwa Anda menyarankan untuk menggunakan []setelah menggunakan find(menurut saya itu bukan niat Anda).
Wolf
Yah, saya pikir 'temukan' bisa lebih baik jika seseorang tidak ingin menyisipkan elemen secara implisit . Membedakan 'temukan' dan mati oleh SIGSEGV bisa lebih disukai.
Gwangmu Lee
1
@ GwangmuLee De-referensi end()iterator adalah perilaku tidak terdefinisi yang tidak perlu menghasilkan SIGSEGV(dan menurut pengalaman saya, hal itu tidak mungkin dilakukan).
Martin York
5

Anda dapat menggunakan std::map::atfungsi anggota, ini mengembalikan referensi ke nilai yang dipetakan dari elemen yang diidentifikasi dengan kunci k.

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

  mymap.at('a') = 10;
  mymap.at('b') = 20;
Manish Sogi
sumber
1

Jika Anda sudah mengetahui kuncinya, Anda dapat langsung memperbarui nilai pada kunci itu menggunakan m[key] = new_value

Berikut ini contoh kode yang mungkin membantu:

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    
abhinav1602
sumber
0

Anda juga bisa melakukan seperti ini-

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

Anda dapat memperbarui nilai seperti berikut

   auto itr = m.find('ch'); 
     if (itr != m.end()){
           (*itr).second = 98;
     }
ZAFIR AHMAD
sumber