2012-05-07 42 views
11

Estoy atascado tratando de descubrir cómo insertar un vector para un valor en un mapa. Por ejemplo:Insertar vector de valor en el mapa en C++

#include <iostream> 
#include <vector> 
#include <map> 

using namespace std; 

int main() 

{ 

    map <int, vector<int> > mymap; 

    mymap.insert(pair<int, vector<int> > (10, #put something here#)); 

    return 0; 
} 

No sé qué sintaxis usar inserte un vector para el valor. Intenté {1,2}, pero eso falló. ¿Qué sintaxis debo usar?

Todo funciona si declaro un vector de antemano y le doy un nombre, pero no quiero hacer eso, ya que quiero tener un mapa con muchos vectores.

gracias de antemano

+0

¿Cómo sabes cuál debe ser el contenido? – mkb

Respuesta

7

Básicamente tu pregunta no trata de insertar std::vector en un std::map. Su pregunta es cómo puede crear fácilmente un anónimostd::vector con valores de elementos iniciales arbitrarios.

En ISO C++ 03, no se puede. C++11 allows using initialization lists for this, sin embargo.

Si le pegan con un compilador de C++ 03, que posiblemente podría crear una función de ayuda para devolver un vector con los elementos especificados:

std::vector<int> make_vector(int a, int b) 
{ 
    std::vector<int> v; 
    v.push_back(a); 
    v.push_back(b); 
    return v; 
} 

Si los vectores que estés inserción son de diferentes tamaños, podría usar una función variadica, aunque hacerlo requeriría que pase la cantidad de elementos o que tenga un valor centinela reservado.

+0

Puede hacer un vector anónimo, pero no con valores. Solo obténgalo como referencia después de que lo hizo y agréguelo después de la construcción. Sin embargo, la función auxiliar es la mejor manera en C++ 03. –

2

#put something here# = vector<int>{1,2}

Me sorprende sin embargo que {1,2} no funcionó. ¿No estás usando un compilador C++ 11? Si no, solo puedes crear el vector con el constructor predeterminado allí (sin valores), o llenarlo con valores primero y pegarlo.

+0

'vector' también tiene un constructor que creará un nuevo vector con n copias del mismo valor inicial. – mkb

+0

mi compilador es Code :: Blocks 10.05, y sus sugerencias no funcionan para mí. Supongo que no se puede hacer con mi compilador. – Akavall

+0

@Akavall, ese es su IDE. Utiliza alguna versión anterior de GCC con el enlace de descarga, por lo que debe actualizar manualmente el compilador y las bibliotecas. – chris

12

Si quieres un vector vacío que podría hacer:

mymap.insert(pair<int,vector<int> >(10, vector<int>())); 

A continuación, puede añadir cualquier elemento que quiera con algo como:

mymap[10].push_back(1); 
mymap[10].push_back(2); 

Editar: la incorrecta afirmación Eliminado el que los vectores se copiaría si/cuando el mapa crezca. Como señalaron los comentaristas, esto no es cierto para std :: map, que está basado en nodos.

+0

'map's almacenar por valor sí, pero crecer el mapa nunca copiará el par clave/valor. Período. Nunca. Así que simplemente pon el vector en él. Lo mismo con 'list',' set', 'multimap', y' multiset'. Se llaman "contenedores basados ​​en nodos" debido a esta propiedad. –

+0

Tu respuesta está equivocada a partir de 'Pero', que es bastante. Hacer crecer un "mapa" no significa mover su contenido. Nunca. Uno de los desafortunados (1) requisitos de 'map' es que una vez establecido un elemento no se moverá hasta que se borre. (1) desafortunado porque se derivó de una implementación conocida en lugar de pensar desde los primeros principios (en el papel del contenedor) e impide implementaciones más eficientes que los árboles rojo-negro, como B-trees. –

5

Si está utilizando C++ 11 Puede utilizar la lista del vector de inicialización constructor (el último constructor en esa lista), que se vería así:

mymap.insert(pair<int, vector<int> > (10, {1, 2, 3})); 

Si sólo se puede utilizar C++ 03, vector tiene un constructor que toma un tamaño y un valor predeterminado para cada elemento que podría ser suficiente para usted. De lo contrario, deberá construir el vector y luego insertarlo. Si se quiere evitar una copia del vector unnessicary al insertar usted podría swap en este modo:

vector<int> myvec; 
myvec.push_back(1); 
myvec.push_back(2); 
mymap[10].swap(myvec); 

De esta manera no será necesario que el vector se puede copiar. Obtendrá una construcción predeterminada del vector adicional, pero eso no es muy caro.

1

Esto debería funcionar en los compiladores de C++ 2003.

#include <iostream> 
#include <vector> 
#include <map> 
#include <cassert> 

using namespace std; 

std::vector<int> make_vector(int a, int b) { 
    std::vector<int> result; 
    result.push_back(a); 
    result.push_back(b); 
    return result; 
} 

int main() 

{ 

    map <int, vector<int> > mymap; 

    mymap.insert(make_pair(10, make_vector(1,2))); 
    // Or, alternatively: 
    // mymap[10] = make_vector(1,2); 

    assert(mymap[10][0] == 1); 
    assert(mymap[10][1] == 2); 

    return 0; 
} 
1

C++ 03 no tiene listas de inicializadores, lo que puede ser un dolor para inicializar las colecciones.

Si no puede actualizar a una versión más moderna del compilador, siempre puede usar la biblioteca Boost.Assignment. Tiene una función list_of precisamente para esto.

#put something here# -> boost::assign::list_of(1)(2) 
Cuestiones relacionadas