Trier pour faire un classement [Résolu]

Signaler
Messages postés
101
Date d'inscription
mercredi 5 novembre 2008
Statut
Membre
Dernière intervention
31 août 2009
-
Messages postés
101
Date d'inscription
mercredi 5 novembre 2008
Statut
Membre
Dernière intervention
31 août 2009
-
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.

26 réponses

Messages postés
327
Date d'inscription
mardi 17 février 2004
Statut
Membre
Dernière intervention
10 avril 2010
8
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();
Messages postés
339
Date d'inscription
dimanche 26 janvier 2003
Statut
Membre
Dernière intervention
25 mars 2009
4
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
Messages postés
101
Date d'inscription
mercredi 5 novembre 2008
Statut
Membre
Dernière intervention
31 août 2009

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.
Messages postés
834
Date d'inscription
samedi 15 novembre 2008
Statut
Membre
Dernière intervention
14 janvier 2017
30
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!
Messages postés
101
Date d'inscription
mercredi 5 novembre 2008
Statut
Membre
Dernière intervention
31 août 2009

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.
Messages postés
327
Date d'inscription
mardi 17 février 2004
Statut
Membre
Dernière intervention
10 avril 2010
8
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 :)
Messages postés
101
Date d'inscription
mercredi 5 novembre 2008
Statut
Membre
Dernière intervention
31 août 2009

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.
Messages postés
327
Date d'inscription
mardi 17 février 2004
Statut
Membre
Dernière intervention
10 avril 2010
8
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.
Messages postés
101
Date d'inscription
mercredi 5 novembre 2008
Statut
Membre
Dernière intervention
31 août 2009

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.
Messages postés
327
Date d'inscription
mardi 17 février 2004
Statut
Membre
Dernière intervention
10 avril 2010
8
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)
Messages postés
101
Date d'inscription
mercredi 5 novembre 2008
Statut
Membre
Dernière intervention
31 août 2009

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  
Messages postés
101
Date d'inscription
mercredi 5 novembre 2008
Statut
Membre
Dernière intervention
31 août 2009

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.
Messages postés
101
Date d'inscription
mercredi 5 novembre 2008
Statut
Membre
Dernière intervention
31 août 2009

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
Messages postés
101
Date d'inscription
mercredi 5 novembre 2008
Statut
Membre
Dernière intervention
31 août 2009

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
Messages postés
101
Date d'inscription
mercredi 5 novembre 2008
Statut
Membre
Dernière intervention
31 août 2009

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
Messages postés
101
Date d'inscription
mercredi 5 novembre 2008
Statut
Membre
Dernière intervention
31 août 2009

Mon code doit être composé que de procédure et de fonction donc je ne peux pas les modifier.

merci
Messages postés
339
Date d'inscription
dimanche 26 janvier 2003
Statut
Membre
Dernière intervention
25 mars 2009
4
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.
Messages postés
327
Date d'inscription
mardi 17 février 2004
Statut
Membre
Dernière intervention
10 avril 2010
8
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 :)
Messages postés
101
Date d'inscription
mercredi 5 novembre 2008
Statut
Membre
Dernière intervention
31 août 2009

ok, mais comment mettre les noms dans le même ordre que les pourcentages puisque je vais modifier l'ordre des pourcentages.

Merci
Messages postés
327
Date d'inscription
mardi 17 février 2004
Statut
Membre
Dernière intervention
10 avril 2010
8
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.