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 :

Liste d'élements communs à plusieurs listes


Sujet :

C#

  1. #1
    Membre éprouvé Avatar de Flow_75
    Femme Profil pro
    Ingénieure
    Inscrit en
    Mai 2005
    Messages
    1 097
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieure
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 097
    Par défaut Liste d'élements communs à plusieurs listes
    Bonjour,

    Voilà j'ai N listes contenant des éléments de type T.

    Je cherche une méthode correctement optimisée permettant de trouver tous les éléments
    se trouvant dans au moins deux listes.

    J'ai un peu de difficultés dans ce genre d'algorithmes.
    Pourriez vous m'aider ?
    Merci.
    Flow

  2. #2
    Membre Expert
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    940
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 940
    Par défaut
    Voici une approche assez simple en utilisant LinQ. Ce n'est pas forcément totalement optimisé mais ça de donnera une base de départ à laquelle comparer d'autres options au niveau performance :

    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
    namespace AtLeastTwo
    {
        internal class Program
        {
            static void Main(string[] args)
            {
                var l1 = new[] { new Item("a"), new Item("b"), new Item("c") };
                var l2 = new[] { new Item("b"), new Item("d"), new Item("e") };
                var l3 = new[] { new Item("d"), new Item("f"), new Item("f") };
                var listOfLists = new[] { l1, l2, l3 };
     
                var comparer = new ItemEqualityComparer();
     
                var result = listOfLists
                    .SelectMany(l => l.Distinct(comparer)) // aplanir les listes en ne conservant pas les doublons de chaque liste
                                                           // (distinct n'est pas nécessaire si les éléments sont déjà uniques)
                    .GroupBy(i => i, comparer) // regrouper les items identiques
                    .Where(g => g.Count() > 1) // ne conserver que ceux qui appraissent plus d'une fois (maintenant on cherche les doublons)
                    .Select(g => g.Key) // garder l'item
                    .ToArray(); // exécuter
     
                Console.WriteLine("[");
                foreach (var s in result)
                {
                    Console.WriteLine(s);
                }
                Console.WriteLine("]");
     
                Console.ReadLine();
            }
        }
     
        internal class Item
        {
            public Item(string value)
            {
                Value = value;
            }
     
            public string Value { get; }
     
            public override string ToString() => Value;
        }
     
        internal class ItemEqualityComparer : IEqualityComparer<Item>
        {
            public bool Equals(Item x, Item y) => x?.Value == y?.Value;
     
            public int GetHashCode(Item obj) => obj?.Value?.GetHashCode() ?? 0;
        }
    }
    Pour optimiser il faut partir du principe que le code qui prend le moins de temps c'est celui qui n'est pas exécuté, donc ça consistera à limiter autant que possible les comparaisons par exemple en supprimant les items déjà sélectionnés. Mais avec ce genre de problème il reste difficile de sortir d'une complexité quadratique.

  3. #3
    Membre éprouvé Avatar de Flow_75
    Femme Profil pro
    Ingénieure
    Inscrit en
    Mai 2005
    Messages
    1 097
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieure
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 097
    Par défaut
    D'accord !

    Merci de ton aide !

  4. #4
    Membre chevronné Avatar de WaterTwelve21
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2015
    Messages
    270
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Décembre 2015
    Messages : 270
    Par défaut
    Bonjour,

    La réponse de Noxen est trés bonne en plus d'être correct, cela m'a fait aussitôt penser que j'ai une méthode d'extention qui a ce rôle dans un de mes projets.

    Je la pose içi, ça pourrai en intéresser certains.

    C'est à un poil prés le même code que Noxen.

    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
     
            /// <summary>
            /// Méthode qui récupère les éléments présents dans plusieurs listes selon le nombre d'occurence
            /// </summary>
            /// <typeparam name="T">le type des éléments</typeparam>
            /// <param name="listOfLists">la liste de listes</param>
            /// <param name="nbOccurence">le nombre d'occurences nécéssaire</param>
            /// <param name="bAtLeast">précision du filtre, si vrai on recherche "au moins", sinon on recherche avec exactitude</param>
            /// <param name="comparer">le comparateur d'égalité, qu'es-ce qui défini que deux éléments soit identiques ?</param>
            /// <returns></returns>
            public static IEnumerable<T> GetElementsByOccurence<T>(this IEnumerable<IEnumerable<T>> listOfLists,int nbOccurence,bool bAtLeast,IEqualityComparer<T> comparer)
            {
                if (!listOfList.Any())
                    return null;
     
                return listOfLists
                       .SelectMany(ls => ls)
                       .GroupBy(item => item, comparer)
                       .Where(group =>  (bAtLeast) ? group.Count() >= nbOccurence : group.Count() == nbOccurence)
                       .Select(group => group.Key);
            }

    Je pense rajouter le Distinct() pour les raisons que cite Noxen, bien qu'avoir des listes avec des doublons j'aime pas mais ca peut arriver.

    Merci !

  5. #5
    Membre Expert
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes
    Inscrit en
    Octobre 2008
    Messages
    1 966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 966
    Billets dans le blog
    7
    Par défaut
    euhhh rien à dire vous êtes au top les gars.

    @Noxen : belle approche commentée qui plus est.


Discussions similaires

  1. [C# 2.0 / VS 2005] Classes communes à plusieurs projets
    Par oodini dans le forum Visual Studio
    Réponses: 10
    Dernier message: 19/07/2006, 14h47
  2. détecter champs communs à plusieurs tables
    Par mick84m dans le forum Requêtes
    Réponses: 2
    Dernier message: 21/06/2006, 14h18
  3. Réponses: 8
    Dernier message: 08/03/2006, 16h12
  4. critère de période commun à plusieurs requete
    Par Nicko29 dans le forum Access
    Réponses: 4
    Dernier message: 26/09/2005, 20h46
  5. Réponses: 5
    Dernier message: 20/09/2005, 22h48

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