2009-10-12 9 views
1

ceci est pour une affectation donc je serai délibérément général. Ma question concerne les décisions de mise en œuvre que j'ai déjà prises - peut-être n'étaient-elles pas bonnes.Comment trier une liste lorsque le critère de tri nécessite une variable supplémentaire? C++

J'ai une liste de pointeurs vers des structures, par ex. list<MyStruct*> bob; À un moment donné, j'ai besoin pour trier ces pointeurs par l'un des membres de données de leurs objectifs et j'ai pu le faire facilement avec

bool sortbyarrival(const MyStruct* a, const MyStruct* b) { 
return a->arrival < b->arrival; 
} 

Et puis en appelant bob.sort(sortbyarrival); Fonctionne très bien.

Maintenant, ailleurs, j'ai besoin de trier par un critère différent, ce qui implique un compteur dans le programme. J'ai besoin de quelque chose comme return counter*a->arrival < counter*b->arrival; Mais la façon dont je viens de décrire est la seule façon dont je sais comment faire un tri, je pense, et je ne sais pas comment passer mon compteur comme argument supplémentaire. Comment puis-je trier cette liste de pointeurs? ETA: Le compteur est juste une variable dans main. Donc, idéalement, je pourrais appeler quelque chose comme bob.sort(sortbyratio, counter); ou sort(bob.begin(), bob.end(), sortbyratio, counter);

+0

est '' list' std :: list', ou un autre type de la STL? – bcat

+0

C'est std :: list, oui. – eom

+0

Je suis confus. Que fait la multiplication des deux côtés par «contre»? – rlbond

Répondre

4

similaires à l'exemple de ltcmelo, mais si les objets eux-mêmes ne contiennent pas le compteur:

struct sort_with_counter { 
    sort_with_counter(const double d): counter(d) {} 

    bool operator()(const MyStruct* a, const MyStruct* b) { 
     return(counter*a->arrival < counter*b->arrival); 
    } 

    const double counter; 
}; 

mylist.sort(sort_with_counter(5.0)); 

Si votre compteur est une variable externe comme si elle n'affectera pas la commande (au moins si elle est positif - merci onebyone!) - donc cela peut en fait ne pas être nécessaire du tout (ou peut-être que je ne comprends pas ce que vous cherchez?). C'est une technique utile dans d'autres cas cependant.

+0

"cela n'affectera pas la commande" - voir la dernière ligne de ma réponse :-) –

+0

Merci - Je pense que le point est toujours important (ce serait une façon étrange d'inverser l'ordre de tri, et je ne pense pas était ce que l'OP avait l'intention de faire) mais il est important d'avoir raison néanmoins :) – Peter

+0

Merci, cela a bien fonctionné pour le problème, que je n'ai pas très bien décrit. Désolé je ne suis pas revenu plus tôt, j'essayais de faire tourner le tout! – eom

0

Juste créer un objet-fonction, une classe/struct avec une surcharge de operator() qui fait le bon choix pour vous. Dans ce cas, en tenant compte des variables supplémentaires. Ensuite, vous passez une instance à la méthode de tri.


struct my_comparison : binary_function<MyStruct const*, MyStruct const*, bool> 
{ 
    bool operator()(MyStruct const* a, MyStruct const* b) 
    { 
    return (a->counter * a->arrival) < (b->counter * b->arrival); 
    } 
}; 

//Use it this way. 
my_comparison comp; 

//Set the arrival and counter data in instance comp. 
/* ... */ 

//Now, pass it to the list. 
bob.sort(comp); 

EDIT: Je viens de remarquer que vous avez une liste de pointeurs alors j'ai changé un peu la struct.

+0

Je ne suis pas sûr que cela fonctionnera - compteur n'est pas un membre de la structure comme vous l'avez montré dans cet exemple, c'est juste une autre variable dans le principal.Est-ce que je pourrais faire ceci comme une surcharge non-binaire comme l'opérateur bool() (MyStruct const & a, MyStruct const & b, int somecounter), etc.? Comment l'appellerais-je alors? Je vous remercie. – eom

+0

Il suffit donc de créer une copie ou une référence ou un pointeur dans MyStruct. Ou utilisez un autre type qui contient le compteur. Ça marchera? –

1

Créer un foncteur, et stocker la valeur supplémentaire dans l'objet foncteur:

struct CompareByCounter { 
    CompareByCounter(int c) : counter(c) {} 
    bool operator()(const MyStruct *lhs, const MyStruct *rhs) { 
     return (counter * lhs->arrival) < (counter * rhs->arrival); 
    } 
private: 
    int counter; 
}; 

// sort ascending 
bob.sort(CompareByCounter(1)); 
// sort descending 
bob.sort(CompareByCounter(-1)); 
Questions connexes