2009-12-14 17 views
7

he el siguiente código:un C++ mapa hash que preserve el orden de inserción

#include <iostream> 
#include "boost/unordered_map.hpp" 

using namespace std; 
using namespace boost; 

int main() 
{ 

    typedef unordered_map<int, int> Map; 
    typedef Map::const_iterator It; 

    Map m; 
    m[11] = 0; 
    m[0] = 1; 
    m[21] = 2; 

    for (It it (m.begin()); it!=m.end(); ++it) 
     cout << it->first << " " << it->second << endl; 

    return 0; 
} 

Sin embargo, yo estoy buscando algo que preserve el orden de modo que después puedo iterar sobre los elementos en el mismo orden en el cual fueron insertados. En mi ordenador el código anterior no conserva el orden, e imprime el siguiente:

0 1 
11 0 
21 2 

pensé que tal vez podría utilizar un boost::multi_index_container

typedef multi_index_container< 
    int, 
    indexed_by< 
     hashed_unique<identity<int> >, 
     sequenced<> 
    > 
> Map; 

Puede alguien mostrar cómo implementar el código original utilizando este contenedor (o cualquier otro contenedor apropiado) para que el iterador siga el orden de inserción?

+1

¿Está manteniendo una lista separada para rastrear el orden de inserción de la pregunta? – Qberticus

Respuesta

11
#include <iostream> 
#include "boost/unordered_map.hpp" 

#include <boost/multi_index_container.hpp> 
#include <boost/multi_index/member.hpp> 
#include <boost/multi_index/ordered_index.hpp> 
#include <boost/multi_index/hashed_index.hpp> 
#include <boost/multi_index/sequenced_index.hpp> 

using namespace std; 
using namespace boost; 
using namespace boost::multi_index; 


struct key_seq{}; 
struct key{}; 

struct Data_t 
{ 
    int key_; 
    int data_; 
    Data_t (int key_v, int data_v) : key_(key_v), data_(data_v) {} 
}; 

int main() 
{ 
    typedef multi_index_container< 
     Data_t, 
     indexed_by< 
      hashed_unique<tag<key>, BOOST_MULTI_INDEX_MEMBER(Data_t,int,key_)>, 
      sequenced<tag<key_seq> > 
     > 
    > Map; 

    typedef Map::const_iterator It; 

    typedef index<Map,key>::type Map_hashed_by_key_index_t; 
    typedef index<Map,key>::type::const_iterator Map_hashed_by_key_iterator_t; 

    typedef index<Map,key_seq>::type Map_sequenced_by_key_index_t; 
    typedef index<Map,key_seq>::type::const_iterator Map_sequenced_by_key_iterator_t; 

    Map m; 
    m.insert(Data_t(11,0)); 
    m.insert(Data_t(0,1)); 
    m.insert(Data_t(21,1)); 

    { 
     cout << "Hashed values\n"; 
     Map_hashed_by_key_iterator_t i = get<key>(m).begin(); 
     Map_hashed_by_key_iterator_t end = get<key>(m).end(); 
     for (;i != end; ++i) { 
      cout << (*i).key_ << " " << (*i).data_ << endl; 
     } 
    } 

    { 
     cout << "Sequenced values\n"; 
     Map_sequenced_by_key_iterator_t i = get<key_seq>(m).begin(); 
     Map_sequenced_by_key_iterator_t end = get<key_seq>(m).end(); 
     for (;i != end; ++i) { 
      cout << (*i).key_ << " " << (*i).data_ << endl; 
     } 
    } 

    return 0; 
} 
+0

Gracias. Aparece un error de compilación con el código anterior en boost 1.41. – dzhelil

+0

He probado este ejemplo con Boost.1.41 y Visual Studio 2005 y todo está bien. ¿Qué compliler y sistema operativo usas? –

+0

Estoy usando i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. compilación 5646) (punto 1) en Snow Leopard. Estoy descargando gcc-4.4 en este momento, espero que compile con la última versión de gcc. – dzhelil

2

Puede intentar crear un mapa ordenado utilizando la combinación de mapa y el vector.

  • El vector puede contener el par de clave y valor.
  • Vector iterator se puede utilizar como iterador para recorrer el mapa ordenado.
  • mapa se puede utilizar para acceder a los elementos más rápido.
+0

No tengo mucha experiencia en C++. ¿Me puede dar una implementación de muestra de su sugerencia? – dzhelil

Cuestiones relacionadas