2011-11-14 18 views
13

Quiero tener un stl list de objetos donde cada objeto contiene dos int. Después quiero ordenar la lista con stl :: sort después del valor de la primera int. ¿Cómo le digo a la función de clasificación que se supone que debe ordenar después de la primera int?Ordenando una lista de un tipo personalizado

Respuesta

24

Puede especificar un predicado de ordenación personalizado. En C++ 11 esto se hace mejor con una lambda:

typedef std::pair<int, int> ipair; 
std::list<ipair> thelist; 

thelist.sort([](const ipair & a, const ipair & b) { return a.first < b.first; }); 

En las versiones anteriores de C++ que tiene que escribir una función apropiada:

bool compFirst(const ipair & a, const ipair & b) { return a.first < b.first; } 

thelist.sort(compFirst); 

(En cambio, si ipair por supuesto puede tener su propia estructura de datos; simplemente modifique la función de comparación para acceder al miembro de datos correspondiente)

Finalmente, si esto tiene sentido, también puede equipar su clase personalizada con un operator<. Eso le permite usar la clase libremente en cualquier contexto ordenado, pero asegúrese de entender las consecuencias de eso.

+0

Hola. Estoy usando tu tipo de "versión anterior" pero sigue dejando un elemento sin clasificar: el último elemento en la lista original no se ordena, siempre queda el último elemento. ¿Sabes lo que podría estar mal? Gracias –

+0

@MarcoCastanho: No creo que eso pueda/deba suceder. Parece que tienes un error en alguna parte. Siéntase libre de publicar una pregunta; asegúrese de crear un ejemplo de reproducción * minimal *. –

2

std :: list :: sort has a one-argument form, siendo el primer argumento la función de comparación.

+1

'std :: sort' tampoco funcionará en' std :: list's ... :-( –

+2

@KerrekSB: Gracias. Algún día buscaré a la persona que decidió que std :: sort no podría solo se especializa para los iteradores de listas, pero se tuvo que incorporar a la clase. – thiton

+0

No. No tiene sentido. La clasificación de listas es totalmente diferente y no tiene nada que ver con los iteradores. El tipo estándar funciona mediante * valores de intercambio * , mientras que el ordenamiento de lista aprovecha la naturaleza del contenedor y simplemente vuelve a enganchar los nodos del elemento. Tenga en cuenta que el ordenamiento de lista no acepta * * un par de iteradores! –

1

Usted puede hacer algo como esto:

typedef std::pair<int,int>; 
list<my_type> test_list; 

bool my_compare (my_type a, my_type b) 
{ 
    return a.first < b.first; 
} 

test_list.sort(my_compare); 

Si el tipo era una estructura o clase que funcionaría así:

struct some_struct{ 
    int first; 
    int second; 
}; 

list<some_struct> test_list; 

bool my_compare (const some_struct& a,const some_struct& b) 
{ 
    return a.first < b.first; 
} 

test_list.sort(my_compare); 

O, alternativamente, se puede definir operator < para su estructura y solo llame al test_list.sort()

Cuestiones relacionadas