2010-10-22 14 views
6

Considérons une classe A ayant un membre x et un std :: vector < A>. Maintenant, c'est une tâche commune de rechercher le maximum x parmi tous les éléments à l'intérieur du vecteur. Clairement, je peux seulement utiliser std :: max_element s'il y a un itérateur sur les x. Mais je dois en écrire un par moi-même, ou simplement faire une simple boucle.Trouver max_element d'un vecteur où un membre est utilisé pour décider si c'est le maximum

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; 
} 

, mais il est si pénible, et je suis si paresseux .. Y at-il une meilleure option?

+0

vous pouvez utiliser 'boost'? – Naveen

+0

Oui, notre projet utilise boost de toute façon, mais comment puis-je utiliser boost pour cela? – math

Répondre

6

Si vous pouvez utiliser boost alors vous pouvez écrire une expression lambda pour le prédicat binaire attendu par 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

Très bien, ça fonctionne comme un charme, et c'est vraiment un raccourci. Je pense que je devrais creuser plus dans les trucs boost :: lambda: D, esp. sa magie de liaison, merci. – math

21

Vous pouvez passer un comparateur à m ax_element. Et si votre compilateur prend en charge les lambdas (il ne doute), cela est facile:

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

nous utilisons plusieurs GCC ici: 4.4.3, 4.3.x, 4.2.x (Mac OSX), MS Visual Studio 2008, et MinGW qui est essentiellement aussi du GCC IIRC. Au moins mon 4.4.3 sous Ubuntu 10.04 me donne l'erreur: "expression primaire attendue avant" ['jeton "Alors quel compilateur aviez-vous en tête? – math

+0

GCC 4.5.x et MSVC 2010. Le dernier MinGW est livré avec 4.5 –

0

Mettre en œuvre operator< dans votre classe, l'appel:

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

Je n'aime pas vraiment implémenter 'operator <' juste pour qu'un algorithme fonctionne. Les inconvénients communs sont que la sémantique peut ne pas être la prévue dans d'autres circonstances et vous ne pouvez pas le faire pour plus d'un seul membre. Considérons un vecteur de villes avec les distances de votre propre ville et fuseau horaire, si vous voulez trouver le plus proche vous surcharger 'operator <' pour travailler sur les distances, si vous voulez travailler les statistiques de fuseau horaire, vous surchargez pour le fuseau horaire, vous ne pouvez pas avoir les deux. Pour une ville, l'interprétation la plus sensée des plus petites est la population, toute autre chose serait surprenante. –

+0

@David: Je suis d'accord que dans le cas d'une ville, l'opérateur Nim