2010-08-05 14 views
7

Tengo un std::list< std::pair<std::string,double> >, que sé que está ordenado según el std::string element.Cómo convertir un std :: list ordenado de std :: pair a un std :: map

Dado que me gustaría hacer un montón de std::find_if basado en el elemento std::string, creo que un std::map<string,double,MyOwnBinaryPredicate> con lower_bound y upper_bound sería más adecuada.

El hecho es que quiero insert elementos en el std::map de una manera eficiente. Así que quiero usar un iterador adicional para hacer que el insert sea más rápido.

Creo que la manera más fácil sería utilizar un const_reverse_iterator que pasar por el std::list y utilizar el begin() del std::map.

¿Lo harías de esta manera, o es una mala idea?

Gracias!

+0

No ponga [C++] en el título. Para eso son las etiquetas. – NullUserException

+0

Con las respuestas proporcionadas por grddev y Luther Blissett, tengo las mismas prestaciones que con mi sugerencia inicial (usando 'begin()', not 'end()'). Sin embargo, ambos son concisos. Acepto la respuesta de grddev por su simplicidad, pero tengo en cuenta el 'std :: inserter'. ¡Gracias a todos! – Wok

Respuesta

11

Si ya tiene una lista ordenada, que se clasifica de acuerdo con el predicado Predicate, sólo puede hacer lo siguiente:

std::list< std::pair<std::string, double> > sorted_list; 
std::map<string, double, Predicate> map(sorted_list.begin(), sorted_list.end()); 

El constructor map ha complejidad del tiempo lineal si la lista está ya clasificado, O (n * log n) de lo contrario. Luego puede trabajar directamente con el mapa como lo haría con cualquier otro.

Si más adelante desea que los resultados de vuelta en su lista usted podría hacer lo contrario:

sorted_list.assign(map.begin(), map.end());
+3

+1: Me olvidé del ctor lineal para ordenarlo. ¡Estupendo! –

+0

La ventaja de esta respuesta es su simplicidad. ¡Gracias! – Wok

4

Puede utilizar std :: copia y std :: insertor:

std::copy(the_list.begin(),the_list.end(),std::inserter(the_map,the_map.begin())); 

porque el iterador para un par lista <> tiene un tipo de valor compatibles para mapear < X, Y> 's iteradores.

+0

std :: inserter()? así aprendes algo nuevo todos los días :) –

+1

+1: Esto tiene un rendimiento igualmente bueno y también funciona con un mapa existente – grddev

+0

Está usando 'std :: inserter (the_map, the_map.begin())' o 'std :: inserter (the_map , the_map.end()) 'mejor aquí, dado que la lista está ordenada? – msandiford

0

Me gustaría simplemente iterar en la lista e insertar cada par en un mapa o utilizar el método ordenado que Luther Blissett ha descrito.
El hecho de que no obtenga lo que intenta hacer significa que dará como resultado un código ilegible o que está muy lejos.
¿Por qué lo haces de esta manera?
¿Puede cambiar el código para devolverle un mapa en lugar de una lista en primer lugar?

+0

Debo utilizar una lista std :: en primer lugar, porque hay elementos que tienen la misma clave std :: string. Luego hay operaciones que me permiten usar un std :: map al final. Podría considerar usar un std :: map un poco antes en el proceso, pero la pregunta aún es relevante en este caso. – Wok

+0

¿ha considerado usar std :: multimap? Vea aquí: http://www.sgi.com/tech/stl/Multimap.html –