C++ Insertando elementos


Ejemplo

Un elemento se puede insertar en un std::map solo si su clave ya no está presente en el mapa. Dado por ejemplo:

std::map< std::string, size_t > fruits_count;
  • Un par clave-valor se inserta en un std::map través de la función miembro insert() . Requiere un pair como argumento:

    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 función insert() devuelve un pair consiste en un iterador y un valor bool :

    • Si la inserción fue exitosa, el iterador apunta al elemento recién insertado, y el valor bool es true .
    • Si ya existía un elemento con la misma key , la inserción falla. Cuando eso sucede, el iterador apunta al elemento que causa el conflicto, y el valor de bool es false .

    El siguiente método se puede utilizar para combinar la inserción y la operación de búsqueda:

    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
    }
    
  • Para mayor comodidad, el contenedor std::map proporciona el operador de subíndices para acceder a los elementos del mapa e insertar otros nuevos si no existen:

    fruits_count["apple"] = 10;
    

    Aunque es más simple, evita que el usuario verifique si el elemento ya existe. Si falta un elemento, std::map::operator[] crea implícitamente, inicializándolo con el constructor predeterminado antes de sobrescribirlo con el valor suministrado.

  • insert() se puede usar para agregar varios elementos a la vez usando una lista de pares. Esta versión de insert () devuelve void:

    fruits_count.insert({{"apricot", 1}, {"jackfruit", 1}, {"lime", 1}, {"mango", 7}}); 
    
  • insert() también se puede usar para agregar elementos mediante el uso de iteradores que denotan el comienzo y el final de los valores de value_type valor:

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

Ejemplo:

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 complejidad del tiempo para una operación de inserción es O (log n) porque std::map se implementa como árboles.

C ++ 11

Un pair puede construirse explícitamente usando make_pair() y emplace() :

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

Si sabemos dónde se insertará el nuevo elemento, entonces podemos usar emplace_hint() para especificar una hint iterador. Si el nuevo elemento se puede insertar justo antes de la hint , entonces la inserción se puede hacer en un tiempo constante. De lo contrario, se comporta de la misma manera que 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);