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

Langage Perl Discussion :

comparaison 2 arrays


Sujet :

Langage Perl

  1. #1
    Membre à l'essai
    Femme Profil pro
    Étudiant
    Inscrit en
    Janvier 2017
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 32
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2017
    Messages : 29
    Points : 23
    Points
    23
    Par défaut comparaison 2 arrays
    Bonsoir ,
    Depuis plusieurs heures que j'essai de trouver une solution à mon problème.. en fait je veux extraire l'intersection entre 2 tableaux, j'ai fait ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    use strict;
    use Data::Dumper;
     
    my @array1 = (1, 2, 3,3,3,3,4);
    my @array2 = (2, 3, 4,4,4);
    my %original = ();
    my @isect = ();
     
    map { $original{$_} = 1 } @array1;
    @isect = grep { $original{$_} } @array2;
     
    print "@isect\n";

    le résultat est 2 3 4 4 4
    mais ce n'est pas vraiment ce que je souhaite avoir l'intersection dois etre : 2 3 4
    un autre exemple si :
    my @array1 = (5,6,5,7);
    my @array2 = (5,6,7,7);
    alors le résultat est : 5 6 7

    Edit: j'ai supprimé le préfixe Perl 6 de ton post, car il ne concerne pas Pel 6 (mais Perl 5). lolo78.

  2. #2
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 378
    Points : 19 054
    Points
    19 054
    Par défaut
    Salut ftina.

    Quelque chose dans ce genre là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    my @array1 = (1,2,3,3,3,3,4);
    my @array2 = (2,3,4,4,4);
     
    my @res = do {my %x; grep {$x{$_}++} do { my %y; grep {!$y{$_}++} @array1}, do { my %z; grep {!$z{$_}++} @array2}};
    print "@res\n";
    Et le résultat obtenu est :
    Pouvez-vous me confirmer que c'est bien le résultat attendu ?

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  3. #3
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Bonjour Ftina,

    d'abord une petite remarque: ton code ne concerne pas Perl 6, mais Perl 5. Donc, s'il te plaît, n'utilise donc pas le préfixe Perl 6 si ce n'est pas du Perl 6. (J'ai corrigé ton post.)

    Ensuite, tu ne précises pas exactement ce qui doit se passer si tu as (par exemple) deux fois la même valeur dans chacun des tableaux. L'intersection de (1, 2, 3,3,3,3,4) et (2,3, 3, 4,4,4) est-elle (2,3,4) ou (2, 3, 3, 4)?

    En supposant que tu veuilles la seconde solution (deux fois la valeur 3 si elle vient deux fois dans chaque tableau) qui me paraît plus logique, tu peux essayer ceci:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    use strict;
    use warnings;
     
    my @array1 = (1, 2, 3, 3, 3, 3,4);
    my @array2 = (2, 3, 3, 4, 4, 4);
     
    my %count_array_1;
    $count_array_1{$_}++ for @array1;
    for my $val (@array2) {
        next unless $count_array_1{$val};
        print "$val ";
        $count_array_1{$val}--;
    }
    Ce qui donne:

  4. #4
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 378
    Points : 19 054
    Points
    19 054
    Par défaut
    Salut lolo78.

    Est-ce que vous compris le problème de Ftina ?
    Ftina a dans ses deux tableaux des doublons et faire en sorte comme s'ils n'existaient pas. Voici les deux tableaux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    my @array1 = (1,2,3,3,3,3,4);
    my @array2 = (2,3,4,4,4);
    et voici ce que Ftina aurait aimé obtenir avant de faire le traitement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    my @array1 = (1,2,3,4);
    my @array2 = (2,3,4);
    Bien sûr, Ftina ne peut pas modifier le contenu des deux tableaux, sinon cela aurait été trop facile à résoudre.
    Le traitement doit en tenir compte, ce que j'ai fait. Et le résultat doit produire ceci, c'est-à-dire sans doublons :
    Les deux exemples donnés sont suffisamment parlant pour lever toutes ambiguïtés.

    Je décompose le traitement en deux phases.
    La première phase consiste à supprimer les doublons dans les deux tableaux. Voici pour le premier tableau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    do { my %y; grep {!$y{$_}++} @array1}
    et voici pour le second tableau :
    [code]do { my %z; grep {!$z{$_}++} @array2}
    Pour la seconde phase, vu que maintenant nous n'avons plus de doublons, nous appliquons la recherche de ce qui est commun :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my @res = do {my %x; grep {$x{$_}++} @tab1, @tab2};
    @tab1 et @tab2 sont des tableaux fictifs sans doublons.
    On remarque aussi que devant "$x", il n'y a pas de "!".

    On peut faire encore plus court que la solution que j'ai proposé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my @res = do {my %x; grep {!$x{$_}++} do {my %y; grep {$y{$_}++} @array1, @array2}};
    Par contre le résultat obtenu n'est pas trié. Il suffit alors d'ajouter la fonction "sort()" à l'expression ci-dessus.

    Sinon Lolo78, le résultat que vous obtenez n'est pas conforme à ce qu'attend Ftina.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  5. #5
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Bonjour Artemus24,

    Je ne crois pas que tu aies compris la demande de Ftina.

    Citation Envoyé par Ftina Voir le message
    je veux extraire l'intersection entre 2 tableaux
    Le mot intersection est important, je crois.

    Autrement dit, d'après ce que je comprends (mais c'est peut-être aussi moi qui n'ai pas compris), elle ne cherche pas à dédoublonner ses tableaux, mais à trouver les éléments communs entre les deux tableaux. Le problème de son code est qu'elle utilise un hachage pour identifier les éléments du premier tableau et que quand elle utilise ce hachage pour décider d'imprimer ou non les valeurs du second tableau, les valeurs en doublons du deuxième tableau (présentes dans le premier) sont imprimées plusieurs fois, même si elles n'existaient qu'une fois dans le premier tableau. C'est à cause de ce bug qu'elle obtient plusieurs fois la valeur 4 alors que celle-ci n'apparaît qu'une seule fois dans le premier tableau.

    Après, il y a deux façons d'interpréter sa demande, comme je l'ai dit dans ma réponse à sa question:
    Ensuite, tu ne précises pas exactement ce qui doit se passer si tu as (par exemple) deux fois la même valeur dans chacun des tableaux. L'intersection de (1, 2, 3,3,3,3,4) et (2,3, 3, 4,4,4) est-elle (2,3,4) ou (2, 3, 3, 4)?
    La seconde option me paraissant plus logique d'après ce que Ftina dit par ailleurs, c'est celle que j'ai mise en œuvre, avec un jeu de données légèrement modifié (la valeur 3 présente au moins deux fois dans chaque tableau) pour mettre cette différence en évidence.

    Si l'on désire aussi dédoublonner, la solution est plus simple conceptuellement. Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    my @array1 = (1, 2, 3, 3, 3, 3,4);
    my @array2 = (2, 3, 3, 4, 4, 4);
     
    my %hash_array_1 = map { $_ => 1} @array1;
    for my $val (@array2) {
        next unless $hash_array_1{$val};
        print "$val ";
        $hash_array_1{$val} = 0;
    }
    Ou, si l'on préfère:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    my %hash_array_1 = map { $_ => 1} @array1;
    print join " ", grep { my $t; $t = 1 if $hash_array_1{$_}; $hash_array_1{$_} = 0; $t;} @array2;

    Attendons le passage de Ftina pour savoir ce qu'elle voulait vraiment.

  6. #6
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 378
    Points : 19 054
    Points
    19 054
    Par défaut
    Salut lolo78.

    Citation Envoyé par Lolo78
    elle ne cherche pas à dédoublonner ses tableaux
    Justement si, et c'est ce que j'ai compris, supprimer les doublons.
    Peu importe que ce soit fait dans les tableaux @array1 et @array2 ou dans le résultat final.

    Citation Envoyé par Lolo78
    mais à trouver les éléments communs entre les deux tableaux.
    "Commun", c'est l'autre nom pour désigner l'intersection entre deux ensembles.
    Mais la question est "avec" ou "sans" les doublons ?

    Je reprends les propos tenus par Ftina :
    Citation Envoyé par Ftina
    le résultat est 2 3 4 4 4 mais ce n'est pas vraiment ce que je souhaite avoir l'intersection dois être : 2 3 4
    Ftina désire obtenir "2 3 4", c'est-à-dire les éléments qui sont communs dans les deux ensembles, mais sans tenir compte des doublons.

    Dans le deuxième exemple :
    Citation Envoyé par Ftina
    un autre exemple si :
    my @array1 = (5,6,5,7);
    my @array2 = (5,6,7,7);
    alors le résultat est : 5 6 7
    le résultat est aussi ce qui est en commun dans les ensembles, mais sans les doublons !

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  7. #7
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Dans les deux exemples qu'elle donne, le problème n'est pas tant la présence de doublons (elle n'emploie d'ailleurs à aucun endroit le mot doublon), mais le fait que l'intersection soit fausse. Dans le premier, elle trouve plusieurs 4 alors que le premier des tableaux n'en contient qu'un seul; dans le second, son code trouve deux 7, alors que l'intersection correcte n'en comporte qu'un seul, puisque le premier tableau n'en a qu'un. Si Ftina voulait simplement dédoublonner, je pense qu'elle sait très bien comment faire. C'est obtenir l'intersection correcte avec les éventuels doublons de part et d'autre qui est plus délicat.

    Mais, encore une fois, attendons le passage de Ftina, elle saura nous dire ce qu'elle recherche vraiment.

  8. #8
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 276
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 276
    Points : 12 717
    Points
    12 717
    Par défaut
    Bonjour,
    Selon le besoin, un simple perldoc -q intersec :
    How do I compute the difference of two arrays? How do I compute the intersection of two arrays?
    Use a hash. Here's code to do both and more. It assumes that each element
    is unique in a given array:

    my (@union, @intersection, @difference);
    my %count = ();
    foreach my $element (@array1, @array2) { $count{$element}++ }
    foreach my $element (keys %count) {
    push @union, $element;
    push @{ $count{$element} > 1 ? \@intersection : \@difference }, $element;
    }

    Note that this is the symmetric difference, that is, all elements in
    either A or in B but not in both. Think of it as an xor operation.
    Mais ici, le parti pris est l'unicité et les données ne sont pas triées...
    Cordialement.

  9. #9
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Ftina utilise un hash dans le code de son post d'origine. J'imagine donc qu'elle connaît cette solution (ou une variante). Mais je persiste à penser qu'elle ne recherche pas l’unicité, car il me paraît assez clair qu'elle aurait su le faire au vu du code qu'elle a posté. Mais nous le le saurons jamais ce qu'elle voulait vraiment si elle ne repasse pas nous le dire. Elle a pris la peine de marquer cette discussion comme résolue, donc on peut penser qu'elle a sa solution, mais malheureusement pas de répondre aux questions qui lui étaient posées.

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

Discussions similaires

  1. [PHP 5.0] Comparaison de deux array
    Par marcq dans le forum Langage
    Réponses: 4
    Dernier message: 08/12/2009, 13h30
  2. tableaux dynamiques - comparaison de array ?
    Par tavarlindar dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 12/05/2008, 12h26
  3. Comparaison de byte array
    Par olibara dans le forum C#
    Réponses: 2
    Dernier message: 06/04/2008, 10h42
  4. [Tableaux] operation sur array, comparaison, addition
    Par frn8cky dans le forum Langage
    Réponses: 4
    Dernier message: 13/10/2007, 10h15
  5. Comparaison de données entre deux arrays
    Par sironimo dans le forum Général Dotnet
    Réponses: 6
    Dernier message: 20/04/2006, 17h44

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