C++ Inserimento di elementi


Esempio

Un elemento può essere inserito in una std::map solo se la sua chiave non è già presente nella mappa. Dato ad esempio:

std::map< std::string, size_t > fruits_count;
  • Una coppia chiave-valore viene inserita in una std::map attraverso la funzione membro insert() . Richiede una pair come argomento:

    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));
    

    La funzione insert() restituisce una pair composta da un iteratore e un valore bool :

    • Se l'inserimento ha avuto successo, l'iteratore punta all'elemento appena inserito e il valore bool è true .
    • Se esisteva già un elemento con la stessa key , l'inserimento fallisce. Quando ciò accade, l'iteratore punta all'elemento che causa il conflitto e il valore bool è false .

    Il seguente metodo può essere utilizzato per combinare operazioni di inserimento e ricerca:

    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
    }
    
  • Per comodità, il contenitore std::map fornisce all'operatore subscript l'accesso agli elementi nella mappa e l'inserimento di nuovi se non esistono:

    fruits_count["apple"] = 10;
    

    Benché più semplice, impedisce all'utente di verificare se l'elemento esiste già. Se manca un elemento, std::map::operator[] lo crea implicitamente, inizializzandolo con il costruttore predefinito prima di sovrascriverlo con il valore fornito.

  • insert() può essere usato per aggiungere più elementi contemporaneamente usando una lista di coppie rinforzate. Questa versione di insert () restituisce void:

    fruits_count.insert({{"apricot", 1}, {"jackfruit", 1}, {"lime", 1}, {"mango", 7}}); 
    
  • insert() può anche essere usato per aggiungere elementi usando gli iteratori che denotano i valori di inizio e fine di 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()); 
    

Esempio:

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
    }
}

La complessità temporale per un'operazione di inserimento è O (log n) perché std::map è implementata come alberi.

C ++ 11

Una pair può essere costruita esplicitamente usando make_pair() ed emplace() :

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

Se sappiamo dove verrà inserito il nuovo elemento, possiamo usare emplace_hint() per specificare un hint iteratore. Se il nuovo elemento può essere inserito prima del hint , l'inserimento può essere eseguito in tempo costante. Altrimenti si comporta allo stesso modo di 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);