2010-07-12 7 views
9

Digamos que tengo una colección de objetos Persona, cada uno de los cuales tiene el siguiente aspecto:¿Qué contenedor STL para datos ordenados con acceso basado en clave?

class Person 
{ 
    string Name; 
    string UniqueID; 
} 

Ahora, los objetos deben ser almacenados en un contenedor que me permite ordenarlos de modo que pueda determinado elemento X con facilidad localizar el elemento X + 1 y X-1.

Sin embargo, también necesito un acceso rápido basado en el UniqueID, ya que la colección será grande y una búsqueda lineal no lo cortará.

Mi 'solución' actual es usar una lista std :: en conjunto con un std :: map. La lista contiene las Personas (para el acceso ordenado) y el mapa se usa para asignar UniqueID a una referencia al elemento de la lista. La actualización del 'contenedor' generalmente implica actualizar tanto el mapa como la lista.

Funciona, pero creo que debería haber una forma más inteligente de hacerlo, tal vez boost:bimap. Sugerencias?

EDIT: Existe cierta confusión sobre mis requisitos para "ordenar". Para explicarlo, los objetos se transmiten secuencialmente desde un archivo, y el 'orden' de los elementos en el contenedor debe coincidir con el orden de los archivos. El orden no está relacionado con los ID.

+1

¿Qué quiere decir con 'X + 1' y' X-1'? Tengo la sensación de que no se refiere al campo 'UniqueID', ¿qué es? ¿A qué orden se refiere? –

+0

Me refiero a los pedidos dentro del contenedor. ej. (asumiendo un vector) Matriz [X], [X-1] y [X + 1] – Roddy

+1

¿Cuál es el orden en el contenedor? Creo que eso es lo que Matthieu está tratando de precisar. – Joel

Respuesta

8

boost:bimap es la opción más obvia. bimap se basa en boost::multi_index, pero bimap tiene una sintaxis simplificada. Personalmente preferiré boost::multi_index sobre boost::bimap porque permitirá agregar fácilmente más índices a la estructura Person en el futuro.

+0

Por cierto, pregunta a hablantes nativos: 'índices' o' índices' –

+3

'Índices' es el sustantivo plural técnicamente correcto.Pero todos entenderían 'índices' ... – Roddy

+0

Gracias. he encontrado frustrantemente que mi toolchain (C++ Builder 2010) no admite boost :: multi_index o bimap, pero bueno, al menos sé lo que * debería * estar usando. – Roddy

7

No hay un contenedor de Biblioteca estándar que haga lo que desea, por lo que deberá usar dos contenedores o la solución Boost. Si utilizo dos contenedores, normalmente preferiría un vector o un deque sobre una lista, en casi todas las circunstancias.

+0

@Neil, gracias. Usar un vector significaría que eliminar o insertar un elemento podría invalidar TODAS las referencias en mi mapa. De ahí la lista. – Roddy

+0

@Roddy: No estoy seguro de sus requisitos, pero tengo una idea de que usa su lista como cola. Si estoy equivocado, no dude en corregirme, pero si estoy en lo cierto, entonces la solución 'deque' de Neil tiene sentido. –

+0

@ Matthieu, lamentablemente no: todavía necesito inserción/eliminación aleatoria que no invalidará las ubicaciones de todos los demás elementos. – Roddy

1

¿Por qué no utilizar dos mapas, uno con Persona como clave y otro con UniqueId como clave, pero eso requiere actualizarlos a ambos?

puede crear una función de devolución de llamada que actualice los mapas cada vez que haya algún cambio.

+0

"puede crear una función de devolución de llamada ..." Ah - ¿cómo hago eso? – Roddy

+2

Al reinventar el Bimap :) –

Cuestiones relacionadas