Trier pour faire un classement [Résolu]

suethi75 101 Messages postés mercredi 5 novembre 2008Date d'inscription 31 août 2009 Dernière intervention - 26 déc. 2008 à 22:29 - Dernière réponse : suethi75 101 Messages postés mercredi 5 novembre 2008Date d'inscription 31 août 2009 Dernière intervention
- 2 janv. 2009 à 10:08
bonsoir,

Je souhaiterai faire un classement. Pour cela j'utilise une collection pour mettre mes valeurs (en l'occurence des %). Ensuite je souhaiterai mettre mes données dans l'ordre pour ensuite en déduire le classement. Mais je n'arrive pas à construire le code.

Merci pour votre aide.
Afficher la suite 

26 réponses

Répondre au sujet
WishhhMaster 327 Messages postés mardi 17 février 2004Date d'inscription 10 avril 2010 Dernière intervention - 26 déc. 2008 à 23:27
+3
Utile
Salut,

Si tu utilises une List, tu peux te servir de la méthode Sort.

List<double> list = new List<double>();
            list.Add(0.2);
            list.Add(0.4);
            list.Add(0.1);
            list.Add(0.34);
            list.Add(0.09);
            list.Add(0.23);

            list.Sort();
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de WishhhMaster
bubbathemaster 342 Messages postés dimanche 26 janvier 2003Date d'inscription 25 mars 2009 Dernière intervention - 27 déc. 2008 à 15:40
+2
Utile
Il va falloir que tu créé une classe candidat qui implemente l'interface IComparable qui stock les données pour un candidate (nom, %, date, etc), puis que tu ajoute tout ça dans une List<Candidat> pour enfin appeler la méthode Sort.

Ie:

public class Candidat : IComparable
    {

        public string Nom;
        public double Resultat;

        public Candidat(string Nom, double Resultat)
        {
            this.Nom = Nom;
            this.Resultat = Resultat;
        }

        #region IComparable Members

        public int CompareTo(object obj)
        {
            if (obj is Candidat)
            {
                Candidat c = (Candidat)obj;
                return -this.Resultat.CompareTo(c.Resultat); //ordre decroissant
            }
            else
            {
                throw new InvalidOperationException();
            }
        }

        #endregion
    }

Et quelque part dans ton programme:

List<Candidat> l = new List<Candidat>();

            l.Add(new Candidat("Toto", 0.1));
            l.Add(new Candidat("Roger", 0.02));
            l.Add(new Candidat("Smartass", 0.94));
            l.Add(new Candidat("Pierre", 0.7));
            l.Add(new Candidat("Noob", 0.4));

            l.Sort();

            string s = "";
            for (int i = 0; i < l.Count; i++)
            {
                s += String.Format("{0} est en position {1} avec le score {2}\r\n", l[i].Nom, i + 1, l[i].Resultat);
            }
            MessageBox.Show(s);

Ce qui donne:
Smartass est en position 1 avec le score 0,94
Pierre est en position 2 avec le score 0,7
Noob est en position 3 avec le score 0,4
Toto est en position 4 avec le score 0,1
Roger est en position 5 avec le score 0,02
Commenter la réponse de bubbathemaster
suethi75 101 Messages postés mercredi 5 novembre 2008Date d'inscription 31 août 2009 Dernière intervention - 27 déc. 2008 à 09:39
0
Utile
Je ne vois pas ce que tu veux dire par liste? Est ce différent de Arraylist? Moi j'utilise une ArrayList.

Que veut dire lz ligne suivante:

List<double> list = new List<double>();

Mais après avoir trié je voudrais attribuer à chacune de mes valeurs une position, par exemple:

55% est 1er du classement
45% est 2eme du classement
40% est 3 eme du classement
ainsi de suite.
 
Moij e pensais trier l'ArrayList et ensuite attribuer chaque valeur, l'index correspondant mais je n'arrive pas à exploiter cette solution.

Désolé, je n'ai pas le code sur ce poste.

Merci pour votre aide.
Commenter la réponse de suethi75
cs_Robert33 835 Messages postés samedi 15 novembre 2008Date d'inscription 14 janvier 2017 Dernière intervention - 27 déc. 2008 à 11:13
0
Utile
Bonjour
je ne connais pas non plus la syntaxe donnée par Wishh, mais ça ressemble au Template du C++, peut être une extension récente du C#.

Pour trier un ArrayList, utilise un objet implémentant IComparer

1- tu te crée une classe qui implémente IComparer (note que tu peux en créer plusieurs)
2- Dans cette classe tu implémente la méthode 'Compare' qui prend 2 paramètres (objet x et objet y)
     Cette méthode doit retourner 0 si tu considère que les objets sont identiques
            -<0 si x est plus petit que y
            >0 si y est plus petit que x
    donc c'est toi qui décide de l'ordre de trie3 - lorsque tu veux trier to ArrayList utilise <?xml:namespace prefix st1 ns "urn:schemas-microsoft-com:office:smarttags" /??><st1:personname w:st="on" productid="la méthode Sort">la méthode Sort</st1:personname> en passant en paramètre une instance de cette classe de trie
4 - Parcours l'ArrayList avec un littérateur (méthode GetEnumerator() de l'ArrayList)

Tu peux ainsi définir autant de méthode de trie que tu le souhaite.

note qu'il existe aussi une classe SortedList qui permet de créer des listes indexées et triables.

public class MonTrie : IComparer 
{
   // on considère que les objets à trier son des entiers   
   int IComparer.Compare( Object x, Object y )  
   {
       int X = (int)x;
       int Y = (int)y
      return(X-Y);    // pour un tri croissant
      return(Y-X);    // pour un tri décroissant
   }
}

C# is amazing, enjoy it!
Commenter la réponse de cs_Robert33
suethi75 101 Messages postés mercredi 5 novembre 2008Date d'inscription 31 août 2009 Dernière intervention - 27 déc. 2008 à 11:23
0
Utile
Merci pour ton explication mais j'ai du mal à comprendre comment ça marche. Pourrais tu me donner un exemple concrêtement avec des valeurs.
Excuse moi je débute.

Merci pour ton aide.
Commenter la réponse de suethi75
WishhhMaster 327 Messages postés mardi 17 février 2004Date d'inscription 10 avril 2010 Dernière intervention - 27 déc. 2008 à 11:37
0
Utile
Salut,

Tu utilises quelle version du framework .Net? Si tu utilises v 2.0 ou ultérieure, tu peux utiliser System.Colletion.Generic.List<> au lieu de ArrayList.

ArrayList contient des objets, donc tu peux tout mettre dedans (int, double, classes, ...), tandis que List<double> ne contient que des éléments de type double. Utiliser les listes génériques sont plus rapides (e.g. tes doubles ne sont pas encapsulés automatiquement en objet quand tu les ajoutes) et plus sûr: tu ne peux pas ajouter quelque chose qui ne correspond pas au type de la liste sans faire exprès.

Tu as dis que tu ne mettais que des pourcentages dans ton array list non ?

 ArrayList al = new ArrayList();
            al.Add(0.5);
            al.Add(0.3);
            al.Add(0.2);
            al.Add(0.7);
            al.Add(0.34);
           
            al.Sort();

Je viens d'essayé ça, ça a l'air de marcher.  Je ne pense pas que tu aies besoin d'implémenter IComparer si tout ce que tu veux est un tri croissant avec des types valeurs (int/float/double...).  Si tu as besoin d'autres sortes de tris, alors oui tu devras sans doute implémenter IComparer. Je n'ai jamais utiliser ArrayList, donc je peux me tromper :)
Commenter la réponse de WishhhMaster
suethi75 101 Messages postés mercredi 5 novembre 2008Date d'inscription 31 août 2009 Dernière intervention - 27 déc. 2008 à 11:45
0
Utile
Oui, je veux faire un tri mais ensuite je veux faire unclassement. C'est à dire, la candidat qui obtient le plus gros pourcentage (ex: 85%) sera 1er ensuite, le deuxième candidat obtient 75% il sera classé 2ème. En fait, je fais un tri sur les pourcentages pour ensuite les classés. Le but final est de donner au candidat son classement par rapport au nombre de candidat.

Dites moi si j'ai été clair, peut être je me suis mal exprimé.

Merci pour votre aide.
Commenter la réponse de suethi75
WishhhMaster 327 Messages postés mardi 17 février 2004Date d'inscription 10 avril 2010 Dernière intervention - 27 déc. 2008 à 11:58
0
Utile
Disons que tu as une classe candidat

Si elle contient un membre "resultat", alors tu peux directement mettre ajouter des instances de cette classe dans ton ArrayList et ensuite implémenter IComparer comme montré plus haut par Robert (sauf qu'au lieu de caster les Objets en int, tu les castes en Candidat, et tu compare les membres resultats)

Si ta classe candidant ne contient pas de membre "résultat" (et que tu ne veux pas l'ajouter), tu peux te créer une nouvelle classe qui fait l'association entre un candidat et un résultat

class CandidatResultat
{
Candidat candidat;//faire propritété
double resultat; //faire propritété
}

et ajouter des instances de cette classes dans ton ArrayList, et là aussi implémenter IComparer, mais en castant les objets en CandidantResultat et comparant les resultats.
Commenter la réponse de WishhhMaster
suethi75 101 Messages postés mercredi 5 novembre 2008Date d'inscription 31 août 2009 Dernière intervention - 27 déc. 2008 à 12:16
0
Utile
Je vais peut être poser des questions bête mais je pense qu'elle me permettront de m'éclaircir l'esprit. Je commence le csharp donc......
Je ne comprend pas trop ce qu'est une classe, une instance?

Pour te donner mon contexte, j'ai un fichier résultat qui est caractérisé comme ceci: nom|prénom|%de bonne réponse|date qcm| classement
Je calcule pourcentage du candidat que j'ajoute dans une collection et donc ensuite je veux trier et faire le classement.

Merci pour tes éclaircissements.
Commenter la réponse de suethi75
WishhhMaster 327 Messages postés mardi 17 février 2004Date d'inscription 10 avril 2010 Dernière intervention - 27 déc. 2008 à 12:32
0
Utile
Une classe en gros c'est la structure (e.g. une classe Personne contient un nom, un prénom,...) tandis que les instances correspondent au objets qui ont cette structure (e.g. tu auras une instance de Personne pour Paul, une pour Pierre,...). Il y a sans doute de meilleurs explications sur google =)

Quand tu calcules un pourcentage de bon résultat pour un certain candidat, tu mets le pourcentage dans une collection, pour ensuite la trier.  Mais après une liste de pourcentage tout seuls ne te sert à rien, il te faut une association entre le pourcentage et le candidat (voir post précédent)
Commenter la réponse de WishhhMaster
suethi75 101 Messages postés mercredi 5 novembre 2008Date d'inscription 31 août 2009 Dernière intervention - 27 déc. 2008 à 13:22
0
Utile
Merci pour tes réponses.
Comment reconnais tu un membre??
Je ne vois pas comment l'association résultat et canididat vont pouvoir me permettre de trouver le classement?

Merci  
Commenter la réponse de suethi75
suethi75 101 Messages postés mercredi 5 novembre 2008Date d'inscription 31 août 2009 Dernière intervention - 28 déc. 2008 à 09:51
0
Utile
Lorsque tu me dis:

"il te faut une association entre le pourcentage et le candidat".

Mais comment dois faire, j'ai du mal à comprendre.Peux tu me donner plus d'indication?

Merci.
Commenter la réponse de suethi75
suethi75 101 Messages postés mercredi 5 novembre 2008Date d'inscription 31 août 2009 Dernière intervention - 28 déc. 2008 à 10:13
0
Utile
Que veux tu dire par:

"il te faut une association entre le pourcentage et le candidat "

Je ne vois ce que je dois faire? Peux tu m'aider un peu plus?

Merci
Commenter la réponse de suethi75
suethi75 101 Messages postés mercredi 5 novembre 2008Date d'inscription 31 août 2009 Dernière intervention - 28 déc. 2008 à 10:20
0
Utile
Ne tiens pas compte des deux messages que je viens d'envoyer, je n'avais pas vu ton script.

Merci pour le script, je vais essayer de l'appliquer à mon programme, au moins je vais voir si j'ai compris comment cela fonctionne
Commenter la réponse de suethi75
suethi75 101 Messages postés mercredi 5 novembre 2008Date d'inscription 31 août 2009 Dernière intervention - 28 déc. 2008 à 11:34
0
Utile
Re,

Je n'arrive pas à l'adapter par rapport mon programme. en fait, tu utilise l'objet, je ne connais pas encore cette méthode. En fait, mon programme est constitué de fonction et procédure, je t'envoi ci joints un morceau de mon code:

// Création du fichier résultat


        static void fichier_score ()
        {
            //Déclaration des variables
            int cptQuest = 0;
            string ligneLueFichierCand = null;
            string repCand;
            int pourcBonneRep;
            int totaux;     
            int totalReponse = 0;
            string ensembleSplitter;
            string rangFinal = "";
            string date;
           
            //Déclaration collection
            ArrayList collectVérif = new ArrayList();
            ArrayList collectPourc = new ArrayList();


            // Déclaration de 2 tableaux
            string[] tablReponseCand = new string[3];
            string[] tabl_nom_prenom = new string[3];
           
            // Ouverture du fichier Candidat en mode lecture
            StreamReader lireFichierCand = File.OpenText(inscription);
    
            // Une boucle pour permettre de lire tout le fichier
            while ((ligneLueFichierCand = lireFichierCand.ReadLine()) != null)
            {
                tablReponseCand = ligneLueFichierCand.Split('|');
                repCand = tablReponseCand[0] + ('|') + tablReponseCand[1] + ('|') + tablReponseCand[2];
               
                // Appel à la fonction pour calculer les bonnes réponses
                totaux = calcul_bonnes_reponses(repCand);
                totalReponse = totalReponse + totaux;


                // Compteur du nombre de question
                cptQuest++;
            }


            // Appel de la fonction permettant de calculer le pourcentage de bonnes réponses
            pourcBonneRep = pourcentage_bonnes_reponses(totalReponse, cptQuest);


            //// Condition permettant de vérifier si il est le meilleur ou pas
            //rangFinal = classement_meilleurScore(pourcBonneRep);


          
            // instruction permettant de donner la date système
            date = DateTime.Now.ToShortDateString();
     
            // Création du fichier score
            FileInfo fichier = new FileInfo(chemin + "fichier_score.txt");
            StreamWriter fichierScore = fichier.AppendText();


            // On splitte
            ensembleSplitter = nomCandidat + ('|') + prenomCandidat +('|') + date + ('|');
            ensembleSplitter = ensembleSplitter + pourcBonneRep + ('|') + rangFinal  ;


            // On ajoute le contenu de ensemble splitter à la collection
            collectVérif.Add(ensembleSplitter);
           
            // Transfert d'une collection à un fichier.txt
              fichierScore.WriteLine(ensembleSplitter);


            // Fermeture du fichier score et candidat
            fichierScore.Close();
            lireFichierCand.Close();


            // Appel à la fonction pour trier les pourcentage???????????????????????????????
            tri(pourcBonneRep);


            Console.ReadKey();
        }


 


 


 


//DETERMINER LE CLASSEMENT


        static int tri(int pourcentage)
        {
            string name;
            string lireLigne_FichierScore = null;
            int rang = 0;
            string[] tabl_FichierScore = new int [5];
            int pourcentage;


            // Déclaration
            ArrayList collectRang = new ArrayList();


            StreamReader lireFichierScore = File.OpenText(chemin + "fichier_score");


            while ((lireLigne_FichierScore = lireFichierScore.ReadLine()) != null)
                tabl_FichierScore = lireLigne_FichierScore.Split('|');
                name = tabl_FichierScore[0];
                pourcentage = tabl_FichierScore[3];


JE BLOQUE PAR ICI !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
               
                collectRang.Add(name, pourcentage);
                collectRang.Sort();


                string s = "";
              
                for (int i = 0; i < collectRang.Count; i++)    
        }

Au départ je ne connait pas le nombre de candidat qui participeront au qcm donc je dois faire une collection.
Comment puis je faire le lien entre le classement du canididat et le nom du canididat. Faut-il utiliser une collection à plusieurs dimensions, est ce que cela existe.

Merci pour ton aide, j'en ai besoin
Commenter la réponse de suethi75
suethi75 101 Messages postés mercredi 5 novembre 2008Date d'inscription 31 août 2009 Dernière intervention - 28 déc. 2008 à 11:35
0
Utile
Mon code doit être composé que de procédure et de fonction donc je ne peux pas les modifier.

merci
Commenter la réponse de suethi75
bubbathemaster 342 Messages postés dimanche 26 janvier 2003Date d'inscription 25 mars 2009 Dernière intervention - 28 déc. 2008 à 11:47
0
Utile
Désolé mais si tu n'arrive toujours pas à t'en sortir avec le truc prémaché que je t'ai donné, va falloir que tu révise les bases de la programmation, je peux pas faire plus.
Bon courage.
Commenter la réponse de bubbathemaster
WishhhMaster 327 Messages postés mardi 17 février 2004Date d'inscription 10 avril 2010 Dernière intervention - 28 déc. 2008 à 12:32
0
Utile
Tu ne peux pas les modifier parce tu ne sais pas comment ou c'est interdit pour ton devoir?
Tu ne peux créer aucune classe/structure???

Une solution est peut-être de
-mettre tes pourcentages dans un tableau (double[])
-mettre les noms dans un tableau dans le même ordre que les pourcentages correspondants (string[])
-manuellement ajouter et classer tes pourcentages dans un ArrayList , et en même temps ajouter tes noms dans un autre ArrayList à l'indice correspondant (utilise la méthode Insert).

A la fin, tu devrais avoir 2 ArrayList, un avec les pourcentages classés et un autre avec les noms, dans le même ordre que les pourcentages.  Donc tu peux savoir quel candidat a obtenu quel pourcentage.  Mais ce serait bien mieux avec des classes...

Si ça ne t'aide pas, je vais abandonner aussi :)
Commenter la réponse de WishhhMaster
suethi75 101 Messages postés mercredi 5 novembre 2008Date d'inscription 31 août 2009 Dernière intervention - 28 déc. 2008 à 14:38
0
Utile
ok, mais comment mettre les noms dans le même ordre que les pourcentages puisque je vais modifier l'ordre des pourcentages.

Merci
Commenter la réponse de suethi75
WishhhMaster 327 Messages postés mardi 17 février 2004Date d'inscription 10 avril 2010 Dernière intervention - 28 déc. 2008 à 21:45
0
Utile
Hmm, dans mon poste précédent il faut utiliser des arraylist au lieu de tableau.

Quand tu lis ton fichier, tu a le nom du candidat et tu calcules son pourcentages de bonnes réponses, hein? A ce moment, tu ajouter le nom et le pourcentages dans 2 arraylist, au même index.  Quand c'est fini, tu dois insérer tes pourcentages dans un nouvel ArrayList, en faisant le classement en même temps que l'insertion.  Comme ça, pour chaque pourcentage que tu insers, tu connais l'indice correspondant et donc tu peux insérer les nom dan un autre ArrayList au même indice

ArrayList names = new ArrayList();//nom dans candidat dans l'ordre que tu les lis
            ArrayList results = new ArrayList(); //pourcentages correspondans au candidats

//valeurs, que tu dois insérer quand tu lis ton fichier
            names.Add("Pierre");
            names.Add("Paul");
            names.Add("Jaques");
            names.Add("Julie");
            names.Add("Emilie");

            results.Add(40);
            results.Add(67);
            results.Add(12);
            results.Add(89);
            results.Add(99);

            ArrayList sortedResults = new ArrayList();//noms dans candidants triés par poucentages correspondants croissants
            ArrayList sortedNames = new ArrayList();//pourcentages par ordre croissant

            for (int i = 0; i < results.Count; i++)//parcours les pourcentages pour les insérer
            {
                int pc = (int)results[i];
                int index;
                for (index = 0; index < sortedResults.Count; index++)//parcours les pourcentages déjà triés
                {
                    if (pc < (int)sortedResults[index])//on a trouvé ou insérer le pourcentage
                        break;
                }
               //insère pourcentage et nom au même indice

                sortedResults.Insert(index, pc);
                sortedNames.Insert(index, names[i]);
            }

            for (int i = sortedResults.Count - 1; i >= 0; i--)
            {
                Console.WriteLine("{0} est en position {1} avec {2}%% de bonnes réponses", sortedNames[i], sortedResults.Count-i, sortedResults[i]);
            }

Ce serait plus optimisé de directement trier les pourcentages pour chaque ligne que tu lis, au lieu de les mettre dans un ArrayList puis de refaire un passage pour les trier, mais bon avec ça c'est un bout de code qui normalement marche.
Commenter la réponse de WishhhMaster

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.

trier pour faire un classement - page 2