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 :

Eliminer les doublons d'un tableau de hachage


Sujet :

Langage Perl

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 38
    Points : 19
    Points
    19
    Par défaut [Résolu] Eliminer les doublons d'un tableau de hachage
    Bonjour,

    J'ai un tableau qui contient des hachages (pour faire simple) et je voudrais éliminer les doublons du tableau (c'est à dire les hachages identiques). Pour le moment, je ne trouve rien qui puisse m'aider. Quelqu'un a une idée ?
    Merci

    Audrey

  2. #2
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    j'ai un script qui permet de supprimer les doublons d'un tableau, je l'ai jamais essayé sur les hash.
    mais peux tu mieuw expliquer ton souci. Ca ressemble à quoi on tableau de hash

  3. #3
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut Re: Eliminer les doublons d'un tableau de hachage
    Bonjour,
    Citation Envoyé par dreydrey
    J'ai un tableau qui contient des hachages
    Qu'est ce que tu appel des hachages? Parce qu'une table de hachage permet ceci :
    Comment définir et utiliser une table associative ?

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 38
    Points : 19
    Points
    19
    Par défaut
    OK, alors mes hâchages ont cette forme là, par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    %ligne1=("time"=>1000, "duree"=>"100", nom=>"secteur");
    %ligne2=("time"=>1000, "duree"=>"100", nom=>"autrechose");
    %ligne3=("time"=>1000, "duree"=>"100", nom=>"secteur");
    %ligne4=("time"=>2000, "duree"=>"200", nom=>"secteur");
     
    push(@tableau,{%ligne1});
    push(@tableau,{%ligne2});
    push(@tableau,{%ligne3});
    push(@tableau,{%ligne4});
    Donc je récupère le tableau @tableau et je voudrais en enlever les doublons, icic, la ligne 1 et la ligne 2.
    J'ai trouvé des trucs pour faire ça, mais sur des scalaires seulement, et ça ne marche pas dans mon cas. En plus, je ne sais même pas comparer les hachages entre eux. Bref, j'y arrive pas quoi.

    Audrey

  5. #5
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    tu veux dire supprimer ligne 1et ligne 3?

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 38
    Points : 19
    Points
    19
    Par défaut
    non, juste une sur 2 n'importe laquelle. Ah j'oubliais le tableau est ordonné selon le clé "time" des hâchages (mais je pense pas que ce soit important).

  7. #7
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    non, je voulais dire que les lignes identiques sont la 1 et 3??? et tu souhaite en suprimer une des deux??

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 38
    Points : 19
    Points
    19
    Par défaut
    oui, voilà, c'est exactement ce que je veux faire.
    Désolée de pas avoir été claire

  9. #9
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    je t'ai fais une fonction qui te renvoie identique ou different losque que tu lui soumme deux hash.
    Tu peux déjà faire un truc avec. Je continue à chercher un bon algo.
    voilà pour l'instant :

    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
     
     
    my %ligne1=("time"=>1000, "duree"=>"100", nom=>"secteur");
    my %ligne2=("time"=>1000, "duree"=>"100", nom=>"autrechose");
    my %ligne3=("time"=>1000, "duree"=>"100", nom=>"secteur");
    my %ligne4=("time"=>2000, "duree"=>"200", nom=>"secteur");
     
    #compare %ligne1 et %ligne2
    print &compare_hash(\%ligne1,\%ligne3);
     
    sub compare_hash {
    	my $hash1 = shift;
    	my $hash2 = shift;;
    	my $ok = "identique";
    	my $no_ok = "different";
    	if (scalar keys %$hash1 != scalar keys %$hash2) {
    		return $no_ok;
    		exit;
    	}
    	foreach my $cle (keys %$hash1) {
    		if (! $$hash2{$cle} ){
    			return $no_ok;
    			exit;
    		}elsif ($$hash1{$cle} ne $$hash2{$cle}) {
    		  return $no_ok;
    		  exit;	
    		}	
    	}
    return $ok;	
    }

  10. #10
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    je ne sais pas combien t'as de hash en tout, mais plus t'en as, plus il te faura de comparaison donc de temps d'execution.
    Petit calcul math.
    4 hash à comparer entre eux => 6 comparaison max
    5 hash => 10 comparaison max
    6 hash => 15 comparaison max

    soit [n * (n-1)]/2 comparaison max à faire.
    donc en fonction de ses qq remarques, revoit ton algo.

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 38
    Points : 19
    Points
    19
    Par défaut
    Ok merci, c'est un 1er pas., ç ame parait assez clair. Tous mes hash ont les mêmes clés donc je vais passer directement à l'étape 2 de la comparaison valeur après valeur.
    Je pense que je vais faire un algo à 2 boucles qui remplit un 2ème tableau au fur et à mesure et qui vérifie à chaque fois. Par contre, mon tableau à des milliers d'entrées, c'est clair que ça prendre du temps, mais bon, je verrai.
    Merci en tout cas.
    Audrey

  12. #12
    tfe
    tfe est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 85
    Points : 95
    Points
    95
    Par défaut
    Je pense qu en utilisant
    sort
    et en comparant l element en cours avec le precedant y a moyen de faire quelque chose de plus performant

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 38
    Points : 19
    Points
    19
    Par défaut
    Effectivement, c'était très très long, j'ai arrêté après une 30aine de minutes.

    L'idée d'utiliser sort est pas mal, du coup, ce que j'essaie maintenant, c'est de trier mon tableau sur toutes les clés.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @tableau = sort {$a->{time} <=> $b->{time} or $a->{image} cmp $b->{image} or $a->{nom} cmp $b->{nom}} @tableau;
    Puis je parcoure ce tableau, et ajoute chaque ligne à un tableau de résultat (@res) sauf si la ligne est identique à la dernière ligne de res (en utilisant la fonction compare_hash).

    Pour le moment j'ai un bug, mais ça ne devrait pas tarder à marcher, en tout cas, le temps à l'air correct.

    Voilà !

  14. #14
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    si ton script n'est pas tres long, tu peux nous le montrer, y a peut etre moyen de l'optimiser!

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 38
    Points : 19
    Points
    19
    Par défaut
    Bien sûr, le voilà :

    Fonction enleveDoublons :

    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
    sub enleveDoublons{
      my @tableau=@_;
      @tableau = sort {$a->{time} <=> $b->{time} or $a->{image} cmp $b->{image} or $a->{nom} cmp $b->{nom}} @tableau;
     
      my @res;
      push(@res,$tableau[0]);
     
      for(my $i=1;$i<@tableau;++$i){
          if( ! same_hash($tableau[$i],$res[$#res])){
            push(@res,$tableau[$i]);
          }
      }
      return @res;
     
    }

    et la fonction same_hash :

    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
    sub same_hash {
       my $hash1 = shift;
       my $hash2 = shift;;
     
       if (scalar keys %$hash1 != scalar keys %$hash2) {
          return 0;
          exit;
       }
     
       foreach my $cle (keys %$hash1) {
          if (! $$hash2{$cle} ){         
             return 0;
             exit;
          }elsif ($$hash1{$cle} ne $$hash2{$cle}) {        
            return 0;
            exit;
          }
       }
    return 1;
    }
    ça marche très bien et dans un temps très respectable !
    :-)

  16. #16
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    ton script me plait bien et est bien ecrit. Juste une remarque.
    Je me demande si tu ne loupe pas des étapes!!!
    Etant donné qu'avant de faire ton push, tu compares ton hash au dernier de ta liste, il peux s'avérer que ton hash soit identique à l'avant des hash de ta liste et du coup, tu le loupera et t'aura des doublons!!!
    verifie ton algo 8)

  17. #17
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 38
    Points : 19
    Points
    19
    Par défaut
    mmmm... je sais pas, vu que je trie le tableau avant, du coup les lignes doublons sont forcément consécutives dans le tableau @tableau, non ?

    Tu penses à un cas particulier où ça ne marcherait pas ?

    Sinon, dans la pratique, ça a l'air de marcher.

    Merci en tout cas

  18. #18
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    Citation Envoyé par dreydrey
    mmmm... je sais pas, vu que je trie le tableau avant, du coup les lignes doublons sont forcément consécutives dans le tableau @tableau, non ?

    Tu penses à un cas particulier où ça ne marcherait pas ?

    Sinon, dans la pratique, ça a l'air de marcher.

    Merci en tout cas
    C'est vrai que les lignes doublons seront consécutives dans le tableau mais peut etre pas forcement en fin de tableau non!!!!!

  19. #19
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 38
    Points : 19
    Points
    19
    Par défaut
    Ben non, j'arrive pas à voir (ce qui ne veut pas dire que j'ai raison)

    Les push, ça ajoute les lignes à la fin du tableau @res, non ?
    Si on imagine :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $tableau[0]={time=>1000, nom=>"nom1",image=>"secteur"};
    $tableau[1]={time=>1000, nom=>"nom1",image=>"secteur"};
    $tableau[2]={time=>2000, nom=>"nom1",image=>"secteur"};
    $tableau[3]={time=>2000, nom=>"nom2",image=>"secteur"};
    $tableau[4]={time=>2000, nom=>"nom2",image=>"secteur"};
    quand $i=1 alors
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $res[0]={time=>1000, nom=>"nom1",image=>"secteur"};
    On compare $tableau[1] et $res[0] -> ce sont les mêmes donc on n'ajoute pas la ligne à @res.

    quand $i=2 , @res n'a pas changé, on compare $tableau[2] à $res[0], ils sont différents.
    On ajoute la ligne à @res

    quand $i=3
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $res[0]={time=>1000, nom=>"nom1",image=>"secteur"};
    $res[1]={time=>2000, nom=>"nom1",image=>"secteur"};
    on compare $tableau[3] à $res[1], ils sont différents, on ajoute la ligne à @res

    quand $i=4
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $res[0]={time=>1000, nom=>"nom1",image=>"secteur"};
    $res[1]={time=>2000, nom=>"nom1",image=>"secteur"};
    $res[2]={time=>2000, nom=>"nom2",image=>"secteur"};
    on compare $tableau[4] à $res[2], ils sont identiques, donc on n'ajoute pas la ligne.

    A la sortie de la boucle, on a donc @res=
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $res[0]={time=>1000, nom=>"nom1",image=>"secteur"};
    $res[1]={time=>2000, nom=>"nom1",image=>"secteur"};
    $res[2]={time=>2000, nom=>"nom2",image=>"secteur"};
    Et ça marche, non ?

    Ou peut être que push ne place pas la ligne à la fin du tableau ? Qu'est ce que je n'ai pas compris ?

  20. #20
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 498 771
    Points
    498 771
    Par défaut
    je suis d'accord avec ton exemple qui marchera à merveille au fait! tres bon algo.
    je me suis trituré l'esprit, mais au final, ton sort est efficace et empeche toute problematique en effet. Bien vu!

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [Tableaux] Eliminer les doublons d'un tableau de tableau
    Par dirty_harry dans le forum Langage
    Réponses: 5
    Dernier message: 25/05/2009, 14h57
  2. eliminer les doublons d'un tableau
    Par wided_instm dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 22/09/2006, 10h56
  3. récupérer les doublons d'un tableau
    Par stoyak dans le forum Langage
    Réponses: 4
    Dernier message: 11/05/2006, 11h50
  4. [XSL] Eliminer les doublons dans un noeud
    Par Shadow aok dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 13/04/2006, 15h17
  5. Eliminer les doublons dans un tableau d'entiers
    Par engi dans le forum Algorithmes et structures de données
    Réponses: 18
    Dernier message: 21/03/2006, 13h59

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