2010-09-02 7 views
5

busco un contenedor, para contener objetos como Empleado (con información: nombre, salario, teléfono ....) que será posible una vez ordenarlo por su nombre (a..z) y otro tiempo, ordénelo por salario, por ejemplo. ¿cuál es la mejor manera de hacerlo? pensé en un mapa, pero luego defino solamente 1 tecla para pasar por apreciaría cada idea (no demasiado avanzado por favor!)contenedor STL con más de 1 método de clasificación en C++

--- --- actualización

que en realidad no necesito siempre mantengo 2 contenedores STL, normalmente tendría 1 (digamos Empleados ordenados por apellido), y cuando lo solicite, no me importa crear un nuevo contenedor STL y volver a cargar todos los elementos, solo que esta vez para ser ordenado por salario, entonces puedo imprimirlo por ese orden. ¿Es posible crear map1 con sort sort, y map2 con sort of sort? de ser así, me encantaría una explicación más detallada \ example para definir estos 2 mapas. Tengo muy poco conocimiento de C++ (primera asignación que me dieron)

Respuesta

17

usando esta versión de std :: sort

template <class RandomAccessIterator, class Compare> 
void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp); 

se puede ordenar en cualquier campo (s) que desea, el suministro de su propia comparador. Por ejemplo

struct CompareSalary 
{ 
    bool operator() (const Employee& a, const Employee& b) const 
    { 
    return a.salary < b.salary; 
    } 
} 

También desde std :: sort es compatible con todos los contenedores que proporciona un iterador al azar Acess, std :: vector no tendrán ningún problema.

+0

Creo que quieres 'operator()'. –

+0

oops tienes razón. fijo. – stijn

6

Proporcionar un funcional a std::sort:

bool byName(Employee left, Employee right) { 
    return left.name < right.name; 
} 

std::vector<Employee> employees; 
std::sort(employees.begin(), employees.end(), byName); 
+0

@Ferruccio, en realidad no esta vez. Estoy pasando un puntero a byName, no llamando por nombre. –

+0

Acabo de atrapar eso y borré mi comentario. Estaba pensando en byName como un funtor. :-) – Ferruccio

+0

@Philip: Añadiría 'const &' a los parámetros, no es necesario activar el constructor de copias para una comparación simple. –

0

Básicamente que se quiere definir múltiples comparador, cada implementarse para cumplir con los diferentes criterios de clasificación. La publicación de Philip Potter da un ejemplo de un criterio de clasificación. Es posible que desee definir algunos más como este.

La sobrecarga del operador menor le permitirá utilizar el método std :: sort solo con los dos primeros parámetros, pero se limitará a un solo criterio de clasificación.

8

Si quieres tanto los criterios de clasificación que estarán disponibles en la misma hora también se puede mirar en Boost MultiIndex

PD: Pero ya que ha mencionado que es nuevo en C++ que no recomendaría el uso de Boost MultiIndex. Es difícil de entender su sintaxis

+1

(esto es boost, no stl, pero) excepto para agregar/borrar entradas (sin contar el recurso necesario entonces), esto es la forma más eficiente de acceder a los datos ordenados de diferentes maneras. Tiene una declaración "funky", pero no es demasiado avanzada cuando seguir los documentos y trabajar con ella es bastante sencillo. – stefaanv

0

¿Desea ordenarlos en todo momento? Como un std :: map does? (Entonces, ¿puede acceder al elemento más bajo con *(coll.begin())?) Si es así, lo que haría es tener dos std :: map's, cada uno lleno de shared_ptr<T>, cada uno de los cuales tiene su propio functor de clasificación, uno para cada criterio de clasificación. De esta manera, no está limitado a un solo operador "menor que" para su tipo de datos, obtiene O (log n) inserta y elimina (std :: map es solo un árbol binario), y los mapas siempre se ordenan .

Tendría que sincronizar la adición y la eliminación para asegurarse de que se agregan y eliminan de ambos mapas, sin embargo.

+1

Básicamente estás reinventando el 10% de 'boost :: multi_index_container ' – MSalters

Cuestiones relacionadas