IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

[C# 2.0] Comment implementer un Tri stable pour un List<T> ?


Sujet :

C#

  1. #1
    Membre régulier
    Inscrit en
    Mars 2002
    Messages
    118
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 118
    Points : 70
    Points
    70
    Par défaut [C# 2.0] Comment implementer un Tri stable pour un List<T> ?
    Bonjour !

    J’ai un petit (ou gros…) problème de tri. J’ai un List<T> et chaque élément correspond à une classe qui contient au moins deux informations visibles sur lesquelles je dois faire un tri. Ma première idée a été d’utiliser le List<T>.Sort. Le problème est que ce tri n’est pas stable (c.-à-d. qu'il garde l'ordre relatif des quantités égales pour la relation d'ordre).

    Est-ce que .NET ou quelqu’un à quelque part à déjà implanté un tri stable en .NET du style d’utilisation du Sort de Microsoft ? Dois-je sortir un livre d’algo et le coder moi-même? Je ne peux pas croire qu’il n’y a pas une solution simple ou que Microsoft n’a pas pensé à ça…

    Merci beaucoup de votre aide !

    Martin

  2. #2
    Membre averti

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    95
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 95
    Points : 350
    Points
    350
    Par défaut
    Citation Envoyé par margagn
    Ma première idée a été d’utiliser le List<T>.Sort. Le problème est que ce tri n’est pas stable (c.-à-d. qu'il garde l'ordre relatif des quantités égales pour la relation d'ordre).

    Est-ce que .NET ou quelqu’un à quelque part à déjà implanté un tri stable en .NET du style d’utilisation du Sort de Microsoft ?
    Lorsque tu implémente la methode compare tu peux prendre un critère secondaire pour éviter d'avoir 2 membres strictements identiques dans ton tri.

  3. #3
    Membre régulier
    Inscrit en
    Mars 2002
    Messages
    118
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 118
    Points : 70
    Points
    70
    Par défaut
    Bonjour Kikos31,

    Est-ce que tu as un exemple ? Je ne suis pas certain de comprendre...

    Merci !

  4. #4
    Membre expérimenté Avatar de davcha
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 258
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 258
    Points : 1 539
    Points
    1 539
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Text;
     
    namespace ConsoleApplication1
    {
        class A : IComparable
        {
            int a, b;
     
            public A(int a, int b) {
                this.a = a;
                this.b = b;
            }
     
            public override string ToString() {
                return "( " + a + " , " + b + " )";
            }
     
            #region IComparable Membres
     
            public int CompareTo(object obj) {
                A other = obj as A;
                if (other == null)
                    throw new ArgumentException("obj is not a A.");
                if (a != other.b)
                    return a - other.a;
                else
                    return b - other.b;
            }
     
            #endregion
        }
     
        class Program
        {
            static void Main(string [] args) {
                List<A> list = new List<A>();
                list.Add(new A(5, 1));
                list.Add(new A(4, 10));
                list.Add(new A(5, -50));
     
                Console.WriteLine("Unsorted :");
                foreach (A a in list)
                    Console.WriteLine(a.ToString());
                list.Sort();
     
                Console.WriteLine("Sorted : ");
                foreach (A a in list)
                    Console.WriteLine(a.ToString());
                Console.ReadKey();
            }
        }
    }

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 652
    Points : 730
    Points
    730
    Par défaut
    Ou en plus court si les valeurs à comparer sont accessibles de l'extérieur, qu'on ne veut pas mettre la comparaison dans la classe (si ça dépend du code client) ou qu'on ne peut pas la modifier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    list.Sort(
      delegate( A x, A y )
        {
          if ( x.Value1 != y.Value1 )
          {
            return x.Value1.CompareTo( y.Value1 );
          }
     
          return x.Value2.CompareTo( y.Value2 );
        } );
    Dans tous les cas le principe est le même. Pour avoir un tri qui donne un résultat prévisible, il faut que la comparaison se fasse sur autant de critères qu'il faut pour que deux éléments ne soient pas identiques (ou que ça n'ait pas d'importance).
    Be wary of strong drink.
    It can make you shoot at tax collectors, and miss.

  6. #6
    Membre régulier
    Inscrit en
    Mars 2002
    Messages
    118
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 118
    Points : 70
    Points
    70
    Par défaut
    Ca fonctionne ! Fantastique !

    Merci beaucoup de votre aide !

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 45
    Points : 35
    Points
    35
    Par défaut Type nullable
    En effet, c'est la bonne solution pour effectuer des tris.

    Le problème reste posé avec les types nullables (int? , DateTime? etc...)

    On ne peut implémenter CompareTo avec ces types, alors comment faire ?

    @+

    Stéphan.

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 45
    Points : 35
    Points
    35
    Par défaut Solution
    Je pense avoir la solution.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int Nullable.Compare<T>(Nullable<T>, Nullable<T>)
    On peut donc comparer les types nullables de manière générique.

    Dans la méthode IComparable CompareTo qui fournit l'ordre de tri par défaut pour .sort() il suffit de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return Nullable.Compare<letype>(objet1.propriete, objet2.propriete)
    Où "letype" est un int, DateTime, Decimal...

    Il est même possible de ne pas préciser le type T en question :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return Nullable.Compare(objet1.propriete, objet2.propriete)
    Si je fais erreur, merci de me corriger

    @+

    Stéphan.

  9. #9
    awd
    awd est déconnecté
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3
    Points : 4
    Points
    4
    Par défaut
    Après 10 minutes de recherche pour réussir à comparer des types nullables. J'ai trouvé la solution dans ce post !

    Je confirme la solution est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return Nullable.Compare<letype>(objet1.propriete, objet2.propriete)
    1000 fois merci
    Alexandre

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment implementer Try catch bloc en java?
    Par stpaul04 dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 21/05/2014, 16h03
  2. [2.0] Comment implémenter un projet de ressources ?
    Par Louis-Guillaume Morand dans le forum Framework .NET
    Réponses: 5
    Dernier message: 01/07/2005, 16h57
  3. Comment faire le tri d'un array of array ?
    Par Tchouffy dans le forum Langage
    Réponses: 1
    Dernier message: 16/06/2005, 20h55
  4. [VB.Net] Comment implémenter une fonction BitWise ?
    Par graphicsxp dans le forum VB.NET
    Réponses: 6
    Dernier message: 20/04/2005, 15h52
  5. comment creer un tableau "stable"
    Par gaut dans le forum C
    Réponses: 16
    Dernier message: 23/07/2003, 16h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo