[C++]tri d'un vecteur sur 2 éléments

Plop les geeks, j’aimerais trier un vecteur un peu casse-bonbons: J’ai trois entiers par élément: l’age, le numéro d’attraction visitée (oui c’est pour un parc d’attractions ^^) et l’effectif de ce couple.

Bref je voudrais que tout ça soit classé par âge du visiteur et que, à âge égal, les valeurs soient triées par numéro de l’attraction. J’ai tenté ça avec stable_sort, mais je n’arrive pas à écrire une comparaison qui tient la route.

Des idées?

Ca a rien a voir avec un tri stable ca. Stable ca signifie que pour 2 elements egaux, l’ordre original est conservé. La tu veux un tri OrderBy / ThenBy. Avec un comparer C#, ca serait 3 lignes. J’imagine que ca doit pas etre plus compliqué en C++. (Si tu mets un bout de code, ca sera surement plus facile de voir ce qui va pas.)

Oui, du coup j’ai changé le titre. Effectivement ce qu’il faut c’est un genre de Order By age, numero.

Pour le code, j’ai un vecteur d’objet DataXY (une classe alakon avec 1 entier et 2 float).
A la base l’opérateur < est redéfini de la sorte:
[codebox]class DataXY
{
private:
int i;
float x; //attraction
float y; //age

public:
	[...]
	bool operator < (const DataXY&) const;

};
bool DataXY::operator < (const DataXY& a) const
{
return getx() < a.getx();
};
[/codebox]

Ptet qu’en modifiant l’opérateur <, je pourrais prendre en compte l’age en plus de l’attraction.

Oui, il te suffit d’affiner un peu ton opérateur < et d’appeler sort() sur ton vector.

[code]bool DataXY::operator < (const DataXY& other) const
{
if (gety() == other.gety())
{
return getx() < other.getx();
}

return gety() < other.gety();

};[/code]
il me semble que c’est la traduction dans ton code de:[quote]classé par âge du visiteur et que, à âge égal, les valeurs soient triées par numéro de l’attraction[/quote]

Remarques annexes:

  • tu as besoin de l’age et de l’attraction en float?
  • tu as une limite de longueur pour tes noms de variables? La, j’ai deja du faire 4x l’aller-retour pour vérifier ce qu’étaient x et y. float age et getAge(), c’est pas plus lisible? pareil, j’ai remplacé ton ‘a’ par ‘other’, on voit mieux qui c’est.
  • c’est un bon procédé de faire un getter pour tes variables au cas ou tu veux les traiter/formatter avant de les renvoyer. Mais si tu es sur (et certain) de ne faire qu’un “return x”, tu peux appeler directement x < other.x (sans probleme d’accessibilité des variables, puisque tu es dans la meme classe).

Merci pour tes remarques. Ce que j’aurais pu préciser dès le début c’est que x et y peuvent être autre chose qu’un numéro et un âge selon les cas d’utilisation, d’où les float au lieu d’int, pareil pour les noms (x et y ne voudront pas toujours dire numéro et âge).

Pour ton dernier point, c’est pas faux.

Je sais ce que j’ai oublié.
vector::sort() n’existe pas, utilise une std::list.

Dans la STL, tu as sort et stable_sort qui peuvent très bien fonctionner sur un vecteur.

Par contre cet opérateur de comparaison n’a pas marché, je fais d’autres tests.

EDIT:
Ayé j’ai trouvé, j’avoue que j’aurais pas pensé à ça :smiley:
Faire un premier Stable_sort sans argument, il prend l’opérateur de comparaison de DataXY (où je compare juste les x).
Après ça, faire un deuxième stable_sort avec une fonction de comparaison en paramètre (où je compare les y).

Le vecteur est alors trié suivant x puis, à x égal, suivant y. Donc dans mon cas par numéro d’attraction puis par âge.

[quote=« Lupuss, post:7, topic: 50963 »]Dans la STL, tu as sort et stable_sort qui peuvent très bien fonctionner sur un vecteur.

Par contre cet opérateur de comparaison n’a pas marché, je fais d’autres tests.

EDIT:
Ayé j’ai trouvé, j’avoue que j’aurais pas pensé à ça :smiley:
Faire un premier Stable_sort sans argument, il prend l’opérateur de comparaison de DataXY (où je compare juste les x).
Après ça, faire un deuxième stable_sort avec une fonction de comparaison en paramètre (où je compare les y).

Le vecteur est alors trié suivant x puis, à x égal, suivant y. Donc dans mon cas par numéro d’attraction puis par âge.[/quote]

Si tu utilises le comparateur que je t’ai filé, normalement tu fais les 2 d’un coup (j’ai pas testé, mais ca devrait pas etre trop loin).

EDIT:En plus, si je lis bien ce que tu as écrit, tu tries une fois selon les x, une fois selon les y? Tu devrais te retrouver avec un vector trié selon les y seulement, alors. Sinon, il y a un probleme avec ton comparateur.

Impec donc :smiley:

Bonne opportunite pour rapeller que comparer des floats, ca marche pas si simplement (si l’ordre est crucial d’etre exact) :smiley:

http://www.cygnus-software.com/papers/comp…aringfloats.htm

[quote=« GloP, post:10, topic: 50963 »]Bonne opportunite pour rapeller que comparer des floats, ca marche pas si simplement (si l’ordre est crucial d’etre exact) :smiley:

http://www.cygnus-software.com/papers/comp…aringfloats.htm[/quote]

Bien vu.

Cela dit, dans la pratique, avec gcc4 et visual200x, chez nous on n’a vraiment aucun probleme de ce genre.
Mais bon, je te soutiens quand même a 100%. Mort aux égalités de flottants.

@LodeRunner: Je pensais comme toi au début, mais justement stable_sort ne touchera pas à l’ordre des x en triant les y. ça m’a surpris aussi :smiley: par contre ton comparo ne marchait vraiment pas, si tu veux je t’enverrai le résultat par PM (pas tout de suite quand même parce que je suis débordé ^^).

@GloP: yep c’est pas bien de comparer des floats, mais dans le cas présent pour repasser en int faudrait aller trifouiller dans une hiérarchie de classes bien bancale. :smiley:

Bon allez, encore une petite nuit blanche à coder des threads…