2010-10-22 14 views
6

Considere una clase A que tenga un miembro xy un std :: vector < A>. Ahora es una tarea común buscar la máxima x entre todos los elementos dentro del vector. Claramente, solo puedo usar std :: max_element si hay un iterador en las x. Pero debo escribir uno por mi cuenta, o simplemente hago un ciclo simple.Encontrar max_element de un vector donde se usa un miembro para decidir si es el máximo

maxSoFar = -std::numeric_limits<double>::max(); 
for(std::vector<A>::const_iterator cit = as.begin(); cit != as.end(); ++cit) 
{ 
    if(cit->x > maxSoFar) 
    maxSoFar = cit->x; 
} 

pero es tan tedioso, y soy muy vago ... ¿Hay una opción mejor?

+0

puede usar 'boost'? – Naveen

+0

Sí, nuestro proyecto usa boost de todos modos, pero ¿cómo uso boost para eso? – math

Respuesta

6

Si puede utilizar boost entonces se puede escribir una expresión lambda para el predicado binario esperado por max_element:

struct A 
{ 
    A(int n): x(n) 
    { 
    } 
    int x; 
}; 

using namespace std; 
using namespace boost::lambda; 

int main() 
{ 
    vector<A> as; 
    as.push_back(A(7)); 
    as.push_back(A(5)); 
    as.push_back(A(3)); 

    vector<A>::iterator iter = max_element(as.begin(), as.end(), bind(&A::x, _2) > bind(&A::x, _1)); 
    int max = iter->x; 
} 
+0

Muy bien, funciona como un amuleto, y esto es realmente un atajo. Creo que debería profundizar más en el boost :: lambda stuff: D, esp. su magia de enlace, gracias. – math

1

1) Cambie la primera línea a la siguiente:

maxSoFar = *(as.begin()); 

2) Implementar un comparador personalizado y utilizar max_element (como lo hubiera querido): http://www.cplusplus.com/reference/algorithm/max_element/

+1

Su primer consejo es realmente muy malo. ¿Qué pasa si as.empty() == cierto? – f0b0s

21

se puede pasar a un comparador m ax_element. Y si su compilador soporta lambdas (probablemente lo hace), esto es fácil:

std::max_element(as.begin(), as.end(), 
    [](A a, A b){ return a.x < b.x; }); 
+0

usamos varios GCC aquí: 4.4.3, 4.3.x, 4.2.x (Mac OSX), MS Visual Studio 2008 y MinGW, que es esencialmente también algo de GCC IIRC. Al menos mi 4.4.3 bajo Ubuntu 10.04 me da el error: "expresión primaria esperada antes" ['token' Entonces, ¿qué compilador tenía en mente? – math

+0

GCC 4.5.x y MSVC 2010. El último MinGW viene con 4.5 –

0

Implementar operator< en su clase, la llamada:

maxSoFar = *(std::max_element(as.begin(), as.end())); 
+5

No me gusta mucho implementar 'operator <' solo para que un algoritmo funcione. Los inconvenientes comunes son que la semántica podría no ser la esperada en otras circunstancias y no se puede hacer eso por más de un solo miembro. Considere un vector de ciudades con distancias desde su propia ciudad y zona horaria, si desea encontrar lo más cercano que sobrecargaría 'operator <' para trabajar en distancias, si desea trabajar estadísticas de zona horaria, sobrecargaría la zona horaria, pero no puedes obtener ambos. Para una ciudad, la interpretación más sensata de la población más pequeña, cualquier otra cosa sería sorprendente. –

+0

@David: estoy de acuerdo en que en el caso de una ciudad, el operador Nim

Cuestiones relacionadas