Maux de tête causé par une fonction de tri

MissSixty Messages postés 18 Date d'inscription mardi 10 août 2004 Statut Membre Dernière intervention 25 août 2004 - 18 août 2004 à 21:23
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 - 19 août 2004 à 00:47
Désespoir...
je me chauffe encore les neurones avec un problème de tri de tableau 2D qui m'apparaît pourtant assez basic. J'ai bien tenté de m'inspirer de codes déjà faits dans les sources ou encore des exemples sur cplusplus.com, mais non, ça sert à rien, je n'y arrive pas !

Voilà... je vais recourir encore à votre aide au risque d'être étiquettée "DÉBUTANTE"... Je me lance donc: j'essaie de mettre en place une fonction toute simple qui me permettrait de trier mon tableau en ordre croissant avec la fonction qsort() en C.

Les éléments à trier se retrouvent dans le tableau suivant:
xyz[i].s[j], où i=nb_noeuds et j=nombre de coordonnées (0=x, 1=y, 2=z).

Je veux utiliser la fonction qsort() et combiner avec fncompare de la façon suivante :

qsort(xyz, ???,sizeof(float), fncompare ???);

Les ??? sont les endroits où je n'ai aucune idée de ce que je dois y insérer... vraiment AUCUNE ! Je comprends comment exploiter cette fonction en 1d, mais en 2d, NIET !!

Je suis donc à la recherche de quelqu'un qui pourrait me donner un exemple de l'utilisation de la fonction qsort() sur un tableau de type structure ou encore qui pourrait me diriger vers un site où l'on retrouve EXPLICITEMENT une telle utilisation... je suis à cours de ressources et ce n'est pas que je n'ai pas chercher !!!

Merci mille fois à celui ou à celle qui pourra m'aider =)

17 réponses

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
18 août 2004 à 21:48
qsort(xyz, nbrLignesTableau, tailleLigneTableau,fncompare);

ciao...
BruNews, Admin CS, MVP Visual C++
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
18 août 2004 à 21:52
oui voila, ca donnerais ca avec un tableau de struct

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
double x,y,z;
} Point;

int fncompar( Point *p1, Point *p2);

int main()
{
Point tab[5] =
{ { 1.5, 5.5, 6.5 }, { 1.5, 5.5, 6.5 },
{ 1.5, 5.5, 6.5 }, { 1.5, 5.5, 6.5 },
{ 1.5, 5.5, 6.5 } };

qsort( tab, sizeof tab / sizeof *tab, sizeof *tab, fncompar );
}

int fncompar( Point *p1, Point *p2)
{
return (p1.x + p1.y + p1.z > p2.x + p2.y + p2.z) ? 1 : 0 ;
}
0
MissSixty Messages postés 18 Date d'inscription mardi 10 août 2004 Statut Membre Dernière intervention 25 août 2004 1
18 août 2004 à 22:21
DJL :
on pourra dire que tu m'auras sorti de la "mémerde" plus d'une fois cette semaine...

Question #1 : qu'est-ce que je mets où il y a ??? selon mon code? (voir plus bas si j'ai bien compris tes explications et m'aider à compléter les ???)
Question #2 : dans la fonction où on définit fncompar et que l'on compare les termes entre eux, qu'arrive t-il si les termes sont égaux?

_____________________

int fncompar (???) //comprend pas quoi mettre là selon mon code

int main {
typedef struct _DBL3 { double s[3]; } DBL3;
DBL3 *xyz_S = new DBL3[nb_lignes-3];
if (xyz_S == NULL) exit(1);

//LES DONNÉES PROVIENNENT D'UN FICHIER
//VOICI COMMENT JE PROCÈDE POUR LES RÉCUPÉRER...
xyz_S[i].s[j] ...

//COPIE DU TABLEAU DANS UN AUTRE POUR NE PAS ECRASER LES DONNEES INITIALES
DBL3 *co_xyz_S = new DBL3[nb_lignes-3];
if (co_xyz_S == NULL) exit(1);

for (int i=0; i<(nb_lignes-3); i++)
for (int j=0; j<3; j++)
co_xyz_S[i].s[j] = xyz_S[i].s[j];

qsort(co_xyz_S, (nb_lignes-3), 3, fncompar); //est-ce mon programme comprend seul ce que veule dire "... sizeof tab / sizeof *tab, sizeof *tab, ..." ou dois-je les remplacer que qqchose

}

int fncompar (???) {
return (xyz[i].s[0] + xyz[i].s[1] + xyz[i].s[2] > xyz[i].s[0] + xyz[i].s[1] + xyz[i].s[2]) ? 1 : 0 ;
} //pas sûre si j'ai bien compris
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
18 août 2004 à 22:44
a la place de 3 il faut mettre la taille en octet d'un element de ton tableau, le plus sur c'est de mettre sizeof *co_xyz_S, c'est equivalent à sizeof co_xyz_S[0]

qsort(co_xyz_S, (nb_lignes-3), sizeof *co_xyz_S, fncompar);

la fonction de comparaison doit retourner un int (a valeur booleenne) et prendre en paramettre un pointeur sur les 2 elements à comparer

int fncompar (const DBL3 *xyz1, const DBL3 *xyz2)
{
return (xyz1[i].s[0] + xyz1[i].s[1] + xyz1[i].s[2] > xyz2[i].s[0] + xyz2[i].s[1] + xyz2[i].s[2]) ? 1 : 0 ;
}

pour rappel, l'operateur ternaire ()?:

( [condition] ) ? [ valeur retournée si vrai ] : [ valeur retournée si faux ]
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
MissSixty Messages postés 18 Date d'inscription mardi 10 août 2004 Statut Membre Dernière intervention 25 août 2004 1
18 août 2004 à 23:01
DJL :

j'ai modifié mon code avec tes suggestions et voici ce que ça me sort comme erreur...

"testIRM.C", line 586.17: 1540-0274 (S) The name lookup for "i" did not find a declaration. //qui correspond au i trouvé dans la fonction fncompar
"testIRM.C", line 699.57: 1540-0064 (S) Syntax error: "(" was expected but "compare" was found. // qui correspond a ce que j'ai dans le qsort()

Je te remets le code que j'ai utilisé :

typedef struct _DBL3 { double s[3]; } DBL3;
int compare (const DBL3 *xyz1, const DBL3 *xyz2)
{
return (xyz1[i].s[0] + xyz1[i].s[1] +xyz1[i].s[2] > xyz2[i].s[0] + xyz2[i].s[1] +xyz2[i].s[2])?1:0;
}; //comment transférer le i là-dedans

int main {
(...)
DBL3 *co_xyz_S = new DBL3[nb_lignes-3];
if (co_xyz_S == NULL) exit(1);

for (int i=0; i<(nb_lignes-3); i++)
for (int j=0; j<3; j++) co_xyz_S[i].s[j] = xyz_S[i].s[j];

qsort(co_xyz_S, (nb_lignes-3), sizeof *co_xyz_S, compare);
//pqoi il ne comprend pas compare

}

MERCI =)
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
18 août 2004 à 23:04
a ouai desolé, j'etais encore dans les tableaux

int compare (const DBL3 *xyz1, const DBL3 *xyz2)
{
return (xyz1->s[0] + xyz1->s[1] +xyz1->s[2] > xyz2->s[0] + xyz2->s[1] +xyz2->s[2])?1:0;
};
0
MissSixty Messages postés 18 Date d'inscription mardi 10 août 2004 Statut Membre Dernière intervention 25 août 2004 1
18 août 2004 à 23:13
Oh lala... en faisant rouler le tout, j'ai obtenu une erreur ! Du genre que j'ai jamais vu auparavant...

La voici (l'erreur s'est produite dans ma fonction fncompar):

"testIRM.C", line 698.53: 1540-0256 (S) A parameter of type "extern "C" int (*)(const void *, const void *)" cannot be initialized with an expression of type "int (const DBL3 *, const DBL3 *)".
"testIRM.C", line 698.53: 1540-1205 (I) The error occurred while converting to parameter 4 of "qsort(void *, size_t, size_t, extern "C" int (*)(const void *, const void *))".
0
MissSixty Messages postés 18 Date d'inscription mardi 10 août 2004 Statut Membre Dernière intervention 25 août 2004 1
18 août 2004 à 23:15
DJL :

je prends 2 minutes pour te mentionner que j'apprécie grandement ton aide ... en plus c'est iper rapido ! =)
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
18 août 2004 à 23:21
cette fois c'est bon, j'avais oublié le caractere generique de la fonction

int compare (const void *_xyz1, const void *_xyz2)
{DBL3 *xyz1 _xyz1, *xyz2 _xyz2;

return (xyz1->s[0] + xyz1->s[1] +xyz1->s[2] > xyz2->s[0] + xyz2->s[1] +xyz2->s[2])?1:0;
};

on aurait aussi pu caster la fonction, mais c'est plus sur comme ca
0
MissSixty Messages postés 18 Date d'inscription mardi 10 août 2004 Statut Membre Dernière intervention 25 août 2004 1
18 août 2004 à 23:31
Merdouille, je suis encore obligée de faire appel à ton aide... le code a planté avec les messages suivants :

"testIRM.C", line 586.17: 1540-0257 (S) An object or reference of type "DBL3 *" cannot be initialized with an expression of type "const void *".
"testIRM.C", line 586.32: 1540-0257 (S) An object or reference of type "DBL3 *" cannot be initialized with an expression of type "const void *".

Pourtant, j'ai bien la même focntion que toi...

int fncompar (const void *_xyz1, const void *_xyz2)
{
typedef struct _DBL3 { double s[3]; } DBL3; DBL3 *xyz1 _xyz1, *xyz2 _xyz2;
return ( (xyz1->s[0] + xyz1->s[1] +xyz1->s[2]) > (xyz2->s[0] + xyz2->s[1] +xyz2->s[2]) )?1:0;
};

et dans mon main() :

qsort(co_xyz_S, (nb_lignes-3), sizeof *co_xyz_S, fncompar);
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
18 août 2004 à 23:32
djl> t'as gagne le titre de chevalier servant du qsort sur ce coup la.

ciao...
BruNews, Admin CS, MVP Visual C++
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
18 août 2004 à 23:34
c'est parce que tu compile en c++ et la conversion void* est pas implicite, faut faire un cast explicite

typedef struct _DBL3 { double s[3]; } DBL3;

int fncompar (const void *_xyz1, const void *_xyz2);

int main()
{
...
}

int fncompar (const void *_xyz1, const void *_xyz2)
{DBL3 *xyz1 (DBL3 *)_xyz1, *xyz2 (DBL3 *)_xyz2;
return ( (xyz1->s[0] + xyz1->s[1] +xyz1->s[2]) > (xyz2->s[0] + xyz2->s[1] +xyz2->s[2]) )?1:0;
};

la ca devrais etre bon
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
18 août 2004 à 23:35
BruNews > ouai, j'y serais arriver mais sans compilo pour tester on oubli toujours un truc
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
18 août 2004 à 23:43
SANS COMPILO ??? alors le titre de maso avec.

ciao...
BruNews, Admin CS, MVP Visual C++
0
MissSixty Messages postés 18 Date d'inscription mardi 10 août 2004 Statut Membre Dernière intervention 25 août 2004 1
18 août 2004 à 23:59
Je sais pas ce que c'est un cast... mais par exemple, j'apprécie grandement le temps que tu as mis pour me répondre ! Et pour cause, ça marche enfin !!!! =)

Ça paraît souvent évident pour les gens pour qui ça fait longtemps qu'ils programment, mais pour ceux qui n'en sont qu'au début... c'est bien quand on peut compter sur eux et ça nous évite bien des maux de tête !

Merci encore =)

PS: par contre, ça pas donné ce que je pensais comme résultat final... mais JE ME CHARGE DE COGITER LÀ-DESSUS ! =)
0
DeAtHCrAsH Messages postés 2670 Date d'inscription vendredi 25 janvier 2002 Statut Membre Dernière intervention 6 février 2013
19 août 2004 à 00:02
On se demande qui va finir avec les plus gros maux de tête!
djl ou MissSixty ?

Shell
0
cs_djl Messages postés 3011 Date d'inscription jeudi 26 septembre 2002 Statut Membre Dernière intervention 27 novembre 2004 7
19 août 2004 à 00:47
ouai, ben moi la je peux plus :D
0
Rejoignez-nous