Suppression des doublons dans un tableau des chaines des caractères - Perl - Programmation
Marsh Posté le 20-02-2013 à 19:45:25
chomp(@Ti);
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+,
Marsh Posté le 21-02-2013 à 11:27:11
Bonjour,
alors comment utiliser use List::MoreUtils qw{uniq}; ??
Marsh Posté le 21-02-2013 à 11:50:48
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+,
Marsh Posté le 21-02-2013 à 19:20:57
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: |
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+,
Marsh Posté le 22-02-2013 à 12:54:05
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 ??
Marsh Posté le 22-02-2013 à 14:11:28
Chez moi ça marche.
Code :
|
C:\Perl>perl enis.pl |
A+,
Marsh Posté le 22-02-2013 à 14:43:05
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+,
Marsh Posté le 22-02-2013 à 18:52:21
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 ???
Marsh Posté le 22-02-2013 à 18:58:29
L'ordre des mots n'est pas perdu, comme vous l'indiquait ma réponse:
C:\Perl>perl enis.pl |
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+,
Marsh Posté le 22-02-2013 à 19:05:44
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
Marsh Posté le 22-02-2013 à 19:34:35
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+,
Marsh Posté le 22-02-2013 à 19:49:24
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 :
|
mais il y a des erreurs , dans tous les cas je suis très reconnaissante d'avoir m'aider , merci beaucoup
Marsh Posté le 22-02-2013 à 20:56:49
rim_enis a écrit : Bonsoir ,
|
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 :
|
et c'est améliorable:
Code :
|
A+,
Marsh Posté le 23-02-2013 à 17:53:19
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+,
Marsh Posté le 28-02-2013 à 21:51:51
Donc c'est pour cela. Faut vivre avec son temps, la version que vous utilisez date de plus de 12 ans.
A+,
Marsh Posté le 20-02-2013 à 19:29:24
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";
}