Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
924 connectés 

  FORUM HardWare.fr
  Programmation
  Perl

  Suppression des doublons dans un tableau des chaines des caractères

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Suppression des doublons dans un tableau des chaines des caractères

n°2176679
rim_enis
j'aime ENIS
Posté le 20-02-2013 à 19:29:24  profilanswer
 

Bonjour à tous ,  
 
J'ai un fichier dont chaque ligne contient un mot, j'ai récupéré le contenu de ce fichier dans un tableau et j'ai essayé de supprimer les doublons , j'ai essayé ce code mais toujours il y a des problèmes  
voilà le code :
 
 @Ti = <F>;
 
 my @unique = ();
  my %dejavu = ();
 
  foreach my $elem ( @Ti )
    {
  chomp(@Ti);
      next if $dejavu{ $elem }++;
      push @unique, $elem;
    }
 
 
 
 
foreach my $val ( @unique ) {
 
 
 print FIC "$val\n";  
 }

mood
Publicité
Posté le 20-02-2013 à 19:29:24  profilanswer
 

n°2176681
gilou
Modérateur
Modzilla
Posté le 20-02-2013 à 19:45:25  profilanswer
 

chomp(@Ti);  [:what has been seen]  
c'est chomp  $elem; que tu voulais faire je suppose.
 
Pour le reste, le code a l'air OK, et sinon, il y a
use List::MoreUtils  qw{uniq};
 
A+,


Message édité par gilou le 20-02-2013 à 19:45:50

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2176796
rim_enis
j'aime ENIS
Posté le 21-02-2013 à 11:27:11  profilanswer
 

Bonjour,  
alors comment utiliser use List::MoreUtils  qw{uniq};  ??

n°2176809
gilou
Modérateur
Modzilla
Posté le 21-02-2013 à 11:50:48  profilanswer
 

:hello: Bonjour,
 
use List::MoreUtils  qw{uniq};
 
my @array;
........
@array = uniq(@array);  # ou my @unique = uniq(@array); si on veut conserver @array tel quel
 
Bon bien sur, List::MoreUtils n'étant pas un module de base, il faut l'avoir ajouté à sa configuration avec ppm, cpan ou autre. En fait, je crois qu'on peut même l'installer directement comme fichier car il n'a pas de dépendances.
 
Sinon, il y a la technique universelle,
my @array;
......
my %seen;
my @unique = grep { ! $seen{$_}++ } @array;
 
ou copier directement dans son code celui de List::MoreUtils, qui utilise cette technique:
 
sub uniq (@) {
    my %seen = ();
    grep { not $seen{$_}++ } @_;
}
 
A+,


Message édité par gilou le 21-02-2013 à 11:58:23

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2176931
rim_enis
j'aime ENIS
Posté le 21-02-2013 à 19:02:39  profilanswer
 

SVP commet ajouter le module  List::MoreUtils ???

n°2176936
gilou
Modérateur
Modzilla
Posté le 21-02-2013 à 19:20:57  profilanswer
 

Euh, vu que vous avez besoin que de uniq, je ne vois pas pourquoi vous ne faites pas comme je vous ai indiqué.

Citation :

ou copier directement dans son code celui de List::MoreUtils, qui utilise cette technique:  
 
sub uniq (@) {  
    my %seen = ();  
    grep { not $seen{$_}++ } @_;  
}


 
Sinon, pour l'ajouter à votre système, ça dépend de la configuration de votre système, ça peut être fait avec ppm (pour une distribution active perl) ou cpan (pour une distribution strawberry perl ou une distribution linux)
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2177054
rim_enis
j'aime ENIS
Posté le 22-02-2013 à 12:54:05  profilanswer
 

j'ai essayé ce code mais il y a un problème que j'arrive pas à le résoudre en fait mon fichier d'entré contient les lignes suivants :
bonjour
bonsoir
bonsoir
madame
bonjour
madame
 
et voila la sortie de programme :
madame
bonsoir
bonjour
bonjour
 
je pas réussi à savoir pourquoi il y a ajout des caractères au mot bonjour et comment résoudre ce problème ??

n°2177073
gilou
Modérateur
Modzilla
Posté le 22-02-2013 à 14:11:28  profilanswer
 

Chez moi ça marche.

Code :
  1. #!/usr/bin/perl
  2. use v5.10.1;
  3. # code propre
  4. use strict;
  5. use warnings;
  6. use autodie;
  7. # uniq de List::MoreUtils
  8. sub uniq (@) {
  9.    my %seen = ();
  10.    grep { not $seen{$_}++ } @_;
  11. }
  12. # lecture des données dans un array
  13. open my $fh, "< enis.txt";
  14. my @a = <$fh>;
  15. close $fh;
  16. # on vire le \n final et les blancs de début et fin de ligne
  17. map {chomp; s/(^\s*|\s*$)//g} @a;
  18. # on vire les doublons
  19. @a = uniq @a;
  20. # On imprime chaque ligne
  21. map {say} @a;


C:\Perl>perl enis.pl
bonjour
bonsoir
madame


A+,


Message édité par gilou le 22-02-2013 à 14:14:21

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2177082
gilou
Modérateur
Modzilla
Posté le 22-02-2013 à 14:43:05  profilanswer
 

Citation :

bonjour

Manifestement, tu n'es pas en encodage ansi, mais en unicode, et il faut en tenir compte:
....
close $fh;
my $line = shift @a;
$line =~ s/^\x{ef}\x{bb}\x{bf}//; #retire la BOM UTF-8 de début de fichier
unshift @a, $line;

map {chomp; s/(^\s*|\s*$)//g} @a;
....
 
Bon, je suis sur la route maintenant, donc pas de réponse avant ce soir.
A+,


Message édité par gilou le 22-02-2013 à 17:51:54

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2177139
rim_enis
j'aime ENIS
Posté le 22-02-2013 à 18:52:21  profilanswer
 

Merci beaucoup gilou pour votre aide , j'ai essayé le code et c'est bien marché sauf que je veux pas perdre l'ordre des mots ... Avez vous une solution ???

mood
Publicité
Posté le 22-02-2013 à 18:52:21  profilanswer
 

n°2177140
gilou
Modérateur
Modzilla
Posté le 22-02-2013 à 18:58:29  profilanswer
 

L'ordre des mots n'est pas perdu, comme vous l'indiquait ma réponse:

C:\Perl>perl enis.pl  
bonjour  
bonsoir  
madame


a partir de:  
-----------------------------
bonjour
bonsoir
bonsoir  
madame
bonjour  
madame  
------------------------------
On voit bien que seule la première occurrence est conservée, dans son ordre d'apparition.
 
A+,


Message édité par gilou le 22-02-2013 à 18:59:38

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2177141
rim_enis
j'aime ENIS
Posté le 22-02-2013 à 19:05:44  profilanswer
 

Moi j'ai utilisé ce code :  
 
 
open(F,'E:\\Mastère_2013\\Script\\IN6.txt') or die ("Erreur d'ouverture " ) ;
 
open(FIC,'>E:\\Mastère_2013\\Script\\OUT.txt') or die ("Erreur de creation " ) ;
 
@Ti = <F>;
close F;
my $line = shift @Ti;  
$line =~ s/^\x{ef}\x{bb}\x{bf}//; #retire la BOM UTF-8 de début de fichier  
unshift @Ti, $line;  
map {chomp; s/(^\s*|\s*$)//g} @Ti;  
 
my %dejavu;
 
foreach my $elem ( @Ti )
{
     $dejavu{$elem} = 1;
}
#print $_ , "\n" foreach keys %dejavu
 
print FIC $_ , "\n" foreach keys %dejavu
 
le fichier d'entré contient :  
Bonjour
Bonsoir
Madame
Bonjour
Rania
Amine
Amine
 
Alors la sortie est la suivante :  
Bonsoir
Rania
Amine
Bonjour
Madame

 Moi je veux qu'il m'affiche :  
Bonjour
Bonsoir
Madame
Rania
Amine

 
 
 
 
 

n°2177151
gilou
Modérateur
Modzilla
Posté le 22-02-2013 à 19:34:35  profilanswer
 

C'est pas une mauvaise idée à la base, sauf que ça ne peut pas marcher parce qu'un hash ne range pas les clés dans leur ordre d'apparition  (et que de plus, pour des raisons de sécurité, l'ordre est systématiquement variable depuis une des toutes dernières versions de perl).
 
A+,


Message édité par gilou le 22-02-2013 à 19:35:07

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2177154
rim_enis
j'aime ENIS
Posté le 22-02-2013 à 19:49:24  profilanswer
 

Bonsoir ,  
J'ai changé un peu le code et normalement c'est bien marché voilà la solution finale  
 
open(F,'E:\\Mastère_2013\\Script_Final\\IN.txt') or die ("Erreur d'ouverture " ) ;
 
open(FIC,'>E:\\Mastère_2013\\Script_Final\\OUT.txt') or die ("Erreur de creation " ) ;
 
@Ti = <F>;
close F;
my $line = shift @Ti;  
$line =~ s/^\x{ef}\x{bb}\x{bf}//; #retire la BOM UTF-8 de début de fichier  
unshift @Ti, $line;  
map {chomp; s/(^\s*|\s*$)//g} @Ti;  
 
my %dejavu;
my @unique = ();  
 
foreach my $elem ( @Ti )
{
     #$dejavu{$elem} = 1;
  next if $dejavu{ $elem }++;  
      push @unique, $elem;  
}
#print $_ , "\n" foreach keys %dejavu
 
#print FIC $_ , "\n" foreach keys %dejavu
foreach my $val ( @unique ) {
 print FIC "$val\n";  
 }
 
j'ai essayé votre code  

Code :
  1. #!/usr/bin/perl
  2. use v5.10.1;
  3. # code propre
  4. use strict;
  5. use warnings;
  6. use autodie;
  7. # uniq de List::MoreUtils
  8. sub uniq (@) {
  9.     my %seen = ();
  10.     grep { not $seen{$_}++ } @_;
  11. }
  12. # lecture des données dans un array
  13. open my $fh, "< enis.txt";
  14. my @a = <$fh>;
  15. close $fh;
  16. # on vire le \n final et les blancs de début et fin de ligne
  17. map {chomp; s/(^\s*|\s*$)//g} @a;
  18. # on vire les doublons
  19. @a = uniq @a;
  20. # On imprime chaque ligne
  21. map {say} @a;


 
mais il y a des erreurs , dans tous les cas je suis très reconnaissante d'avoir m'aider , merci beaucoup :)

n°2177161
gilou
Modérateur
Modzilla
Posté le 22-02-2013 à 20:56:49  profilanswer
 

rim_enis a écrit :

Bonsoir ,  
j'ai essayé votre code  

Code :
  1. #!/usr/bin/perl
  2. use v5.10.1;
  3. # code propre
  4. use strict;
  5. use warnings;
  6. use autodie;
  7. # uniq de List::MoreUtils
  8. sub uniq (@) {
  9.    my %seen = ();
  10.    grep { not $seen{$_}++ } @_;
  11. }
  12. # lecture des données dans un array
  13. open my $fh, "< enis.txt";
  14. my @a = <$fh>;
  15. close $fh;
  16. # on vire le \n final et les blancs de début et fin de ligne
  17. map {chomp; s/(^\s*|\s*$)//g} @a;
  18. # on vire les doublons
  19. @a = uniq @a;
  20. # On imprime chaque ligne
  21. map {say} @a;


 
mais il y a des erreurs , dans tous les cas je suis très reconnaissante d'avoir m'aider , merci beaucoup :)

Non, il n'y a pas d'erreurs (c'est du code particulièrement simple) si vous remplacez le nom du fichier correctement (enis.txt -> E:\\Mastère_2013\\Script_Final\\IN.txt) et si vous avez un perl récent (v5.16 par exemple)
 
Par contre, il y en a dans votre code:
> open(F,'E:\\Mastère_2013\\Script_Final\\IN.txt') or die ("Erreur d'ouverture " ) ;  
Non, c'est
open(F,'E:\Mastère_2013\Script_Final\IN.txt') or die ("Erreur d'ouverture " ) ;  
ou bien
open(F,"E:\\Mastère_2013\\Script_Final\\IN.txt" ) or die ("Erreur d'ouverture " ) ;  
Si vous utilisez les " " pour les chaines, il faut \\, mais si vous utilisez ' ', alors il faut \ et non pas \\.
 
Il manque un close FIC; final.
D'autre part, vous utilisez des globs pour les filehandlers (F, FIC), ce qui marche, mais est loin d'être très moderne comme approche.
 
> open(F,'E:\\Mastère_2013\\Script_Final\\IN.txt') or die ("Erreur d'ouverture " )
l'utilisation de  
use autodie;  
rend la partie avec die(...) superflue, et devrait être standard dans tout code perl moderne.
D'autre part, vous n'indiquez pas explicitement que c'est une ouverture en lecture seulement.
 
>open(FIC,'>E:\\Mastère_2013\\Script_Final\\OUT.txt') or die ("Erreur de creation " ) ;
ça ne sert a rien d'ouvrir un fichier qu'on n'utilise pas immédiatement ensuite.  
 
Enfin, il faut être cohérent dans le style, et choisir entre
open(F,...); et close(F);
ou
open F, ...; et close F;
Mais pas un mélange des deux styles.
 
enfin, utilisez systématiquement des variables locales:
my @Ti = <...>; et non pas @Ti = <...>;
 
Donc dans un premier temps, votre code devrait ressembler à ceci:

Code :
  1. #!/usr/bin/perl
  2. use v5.10.1;
  3. # code propre
  4. use strict;
  5. use warnings;
  6. use autodie;
  7.  
  8. open(F, "< E:\\Mastère_2013\\Script_Final\\IN.txt" );
  9. my @Ti = <F>;
  10. close(F);
  11.  
  12. my $line = shift @Ti;
  13. $line =~ s/^\x{ef}\x{bb}\x{bf}//; #retire la BOM UTF-8 de début de fichier
  14. unshift @Ti, $line;
  15. map {chomp; s/(^\s*|\s*$)//g} @Ti;
  16.  
  17. my %dejavu;
  18. my @unique = ();
  19.  
  20. foreach my $elem ( @Ti )
  21. {
  22.  next if $dejavu{ $elem }++;
  23.  push @unique, $elem;
  24. }
  25.  
  26. open(FIC, "> E:\\Mastère_2013\\Script_Final\\OUT.txt" );
  27. foreach my $val ( @unique ) {
  28.  print FIC "$val\n";
  29. }
  30. close(FIC);


 
et c'est améliorable:

Code :
  1. #!/usr/bin/perl
  2. use v5.10.1;
  3. # code propre
  4. use strict;
  5. use warnings;
  6. use autodie;
  7.  
  8. open(F, "< E:\\Mastère_2013\\Script_Final\\IN.txt" );
  9. my @Ti = <F>;
  10. close(F);
  11.  
  12. my $line = shift @Ti;
  13. $line =~ s/^\x{ef}\x{bb}\x{bf}//; #retire la BOM UTF-8 de début de fichier
  14. unshift @Ti, $line;
  15. map {chomp; s/(^\s*|\s*$)//g} @Ti;
  16.  
  17. my (%dejavu, @unique);
  18. map {push @unique, $_ unless $dejavu{ $_ }++} @Ti;
  19.  
  20. open(FIC, "> E:\\Mastère_2013\\Script_Final\\OUT.txt" );
  21. map {print FIC "$_\n"} @unique;
  22. close(FIC);


 
A+,
 
 
 


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2177213
rim_enis
j'aime ENIS
Posté le 23-02-2013 à 16:47:41  profilanswer
 

Bonsoir
j'ai toujours un problème avec use autodie;

n°2177215
gilou
Modérateur
Modzilla
Posté le 23-02-2013 à 17:53:19  profilanswer
 

Parce que vous n'avez pas une version ou le module autodie est installé par défaut, c'est bizarre, parce que ce devrait être le cas a partir de la version  v5.10.1, c'est même pour cela que j'ai mis exprès use  v5.10.1; avant.
 
Quand vous faites perl -v, ça vous donne quoi comme numéro de version?
 
A+,


Message édité par gilou le 23-02-2013 à 17:54:18

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2178058
rim_enis
j'aime ENIS
Posté le 28-02-2013 à 19:51:18  profilanswer
 

Bonjour,  
C'est la version 5.6.1 :)

n°2178067
gilou
Modérateur
Modzilla
Posté le 28-02-2013 à 21:51:51  profilanswer
 

Donc c'est pour cela. Faut vivre avec son temps, la version que vous utilisez date de plus de 12 ans.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Perl

  Suppression des doublons dans un tableau des chaines des caractères

 

Sujets relatifs
Probleme : Tableau de pointeurs sur structureExercice java débutant Trie tableau
couleur tableau fct result valeur colonne csvAide VBA, Somme de chaque ligne d'un tableau
tableau 2D dynamiqueTableau :/
Comment initialiser un tableau 2 dimensions de manière dynamique ?Opérations sur les valeurs d'un tableau
un algo qui supp le min et le max d'1 tableau à la fois SVP[c][Transfer de donnees d´un tableau bidimensionel vers unidimensione]
Plus de sujets relatifs à : Suppression des doublons dans un tableau des chaines des caractères


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR