Trier tableau - max en perl

Résolu/Fermé
wafa_o Messages postés 109 Date d'inscription mercredi 16 juillet 2008 Statut Membre Dernière intervention 4 janvier 2011 - 24 déc. 2009 à 13:02
wafa_o Messages postés 109 Date d'inscription mercredi 16 juillet 2008 Statut Membre Dernière intervention 4 janvier 2011 - 28 déc. 2009 à 09:35
Bonjour,

Je souhaite obtenir la 2ème valeur max d'un fichier.
Par exemple, j'ai le fichier suivant :
machine1 00:00 18
machine1 01:00 25
machine1 02:00 6
machine2 13:00 58
machine2 14:00 16
machine2 15:00 75

Je voudrais avoir le résultat suivant
machine1 01:00 18
machine2 14:00 58

J'ai essayé la commande my @tri = sort { $a->[2] <=> $b->[2] } @val; en ayant placé mes champs dans le tableau @val mais ca ne fonctionne pas.
Merci d'avance à ceux qui pourront m'aider.
A voir également:

17 réponses

Salut,

Selon moi, il ne se produira pas.
Si tu le dis.

Essaie ça

lami20j@debian-vbox:/mnt/vbox/perl$ cat tri.pl 
#!/usr/bin/perl
use strict;use warnings;
my %h;
while(<DATA>){
  next if /^$/;
  my @t=split;
  push @{$h{$t[0]}}, join " ",@t[1..2];
}
for my $k(sort keys %h){
  my @t=map  { $_->[0] } 
        sort { $b->[2] <=> $a->[2] } 
	map  { [$_, split ] } 
	@{$h{$k}};
  print "$k $t[1]\n";
}
__END__
A 00:00 15
A 01:00 52
A 02:00 35
A 03:00 16
A 04:00 65
A 05:00 84
A 06:00 41

B 00:00 45
B 01:00 16
B 02:00 98
B 03:00 102
B 04:00 10
B 05:00 9
B 06:00 43

C 00:00 12
C 01:00 85
C 02:00 35
C 03:00 17
C 04:00 66
C 05:00 48
C 06:00 26

Le résultat
lami20j@debian-vbox:/mnt/vbox/perl$ perl tri.pl
A 04:00 65
B 02:00 98
C 04:00 66
1
Salut,

Si je comprends bien tu ne veux pas toucher les 2 premières colonnes et trier seulement la 3ème?
0
wafa_o Messages postés 109 Date d'inscription mercredi 16 juillet 2008 Statut Membre Dernière intervention 4 janvier 2011 2
24 déc. 2009 à 14:41
Oui c'est ca, je ne touche pas aux deux premières colonnes. Seulement à l'affichage je veux recuperer les valeurs des colonnes 1 et 2 qui correspondent à la valeur de la colonne 3.
0
Re,

Tu as du te tromper puisque avant18 il y a 16
machine1 01:00 18
Ca doit être comme ça?
lami20j@debian:~$ cat tri.pl
#!/usr/bin/perl
use strict;use warnings;
my (@f,@t,@tri,@final);

while(<DATA>){
  push @f, [ (split /\s+/)[0..1] ];
  push @t,$1 if /\s(\d+)$/;
}

@tri = sort {$a <=> $b} @t;
print "@$_ ",shift @tri,"\n" for @f;
__END__
machine1 00:00 18
machine1 01:00 25
machine1 02:00 6
machine2 13:00 58
machine2 14:00 16
machine2 15:00 75
lami20j@debian:~$ perl tri.pl
machine1 00:00 6
machine1 01:00 16
machine1 02:00 18
machine2 13:00 25
machine2 14:00 58

machine2 15:00 75
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
wafa_o Messages postés 109 Date d'inscription mercredi 16 juillet 2008 Statut Membre Dernière intervention 4 janvier 2011 2
24 déc. 2009 à 16:27
Euh, non ce n'était pas une erreur.
Je crois que ce n'était pas claire.

En fait je voudrais la seconde valeur max pour toutes les machines.

Exemple :

machine1 00:00 18
machine1 01:00 25
machine1 02:00 6
machine2 13:00 58
machine2 14:00 16
machine2 15:00 75

La 2nd valeur max de la machine 1 est 18 à 00:00
La 2nd valeur max de la machine 2 est 58 à 13:00

Résultat :
machine1 01:00 18
machine2 14:00 58


Je parlais de trie parce que c'est la première idée qui m'est venue à l'esprit pour obtenir le résultat.
0
Re,


En fait je voudrais la seconde valeur max pour toutes les machines.
Je ne comprends pas.
Le champs de milieu ne compte pas?

machine1 00:00 18
machine1 01:00 25
machine1 02:00 6


Ici il y a une machine non?
Pourquoi machine1 01:00 18 et pas machine1 01:00 25 ou machine1 00:00 25
0
wafa_o Messages postés 109 Date d'inscription mercredi 16 juillet 2008 Statut Membre Dernière intervention 4 janvier 2011 2
24 déc. 2009 à 16:38
Dans l'exemple donné, il y a deux machine1 et machine2.

Pour la machine 1 :
machine1 00:00 18
machine1 01:00 25
machine1 02:00 6

J'ai trois valeurs à des heures différentes. Je veux le 2ème max soit 18.
Pour la machine 1 j'ai la valeur 18 à 00:00.


Un autre exemple :
machine1 00:00 18
machine1 01:00 25
machine1 02:00 6
machine1 03:00 78
machine1 04:00 41
machine1 05:00 35

Dans ce cas là, le resultat doit être :
machine1 04:00 41


Tu comprends ?
0
Re,

Non, je ne comprends pas ;-(

Pourquoi tu veux machine1 04:00 41 et pas machine1 05:00 41? C'est toujours la machine 1 non?

Je ne comprends pas ton raisonnement. Si je n'ai pas des critères claires je ne peux rien faire.
0
wafa_o Messages postés 109 Date d'inscription mercredi 16 juillet 2008 Statut Membre Dernière intervention 4 janvier 2011 2
24 déc. 2009 à 16:50
Oui c'est toujours la machine1 mais c'est pas la même heure.
Je recupère la ligne entière où j'ai 41. Dans mon exemple, pour la valeur 41 à gauche j'ai 04:00 et machine1.

machine1 05:00 correspond à la valeur 35, pas 41.

C'est plus claire ;) ?
0
Re,

Oui c'est toujours la machine1 mais c'est pas la même heure.
D'accord, mais en ce cas si l'heure compte, alors il n'y a rien à trier puisque l'heure ne correspond jamais dans ton exemple.

J'aurais compris si j'avais
machine1 01:00 15
machine1 01:00 25

et que tu veux obtenir
machine 01:00 25
0
wafa_o Messages postés 109 Date d'inscription mercredi 16 juillet 2008 Statut Membre Dernière intervention 4 janvier 2011 2
25 déc. 2009 à 10:46
Salut

Le trie était mon idée de départ, c'est certainement pour ca que je n'y arrivais pas.
Est ce que tu as des pistes à me suggérer ?
0
Salut,

Je te propose de me donner un exemple concret (avec plusieurs machines et plusieurs heures) de ce que tu veux et je m'en occuperai, puisque je n'ai pas compris ce que tu veux obtenir. Tant que je ne comprends pas je ne peux rien faire ;-(
0
wafa_o Messages postés 109 Date d'inscription mercredi 16 juillet 2008 Statut Membre Dernière intervention 4 janvier 2011 2
25 déc. 2009 à 16:19
Ok, merci.
J'ai appelé les machines A, B, C. Ce sera plus lisible j'espère.

Alors un exemple d'un fichier avec le contenu :
Colonne 1 Colonne 2 Colonne 3
A 00:00 15
A 01:00 52
A 02:00 35
A 03:00 16
A 04:00 65
A 05:00 84
A 06:00 41

B 00:00 45
B 01:00 16
B 02:00 98
B 03:00 102
B 04:00 10
B 05:00 9
B 06:00 43

C 00:00 12
C 01:00 85
C 02:00 35
C 03:00 17
C 04:00 66
C 05:00 48
C 06:00 26


Et le résultat que je souhaite est :
A 04:00 65
B 02:00 98
C 04:00 66

Il y a 3 colonnes. La colonne 1 représente les machines. Dans l'exemple il y en a 3 (A, B et C)
Prenons le cas de la machine A.
A différentes heures (colonne 2), la machine A a réalisé un certain nombre de pièces (colonne 3).

Je voudrais afficher pour chaque machine:
- Le nom de la machine en question
- l'heure à laquelle elle a réalisé X pièces (X étant la 2ème valeur max de pièce).
- la valeur X

(Par exemple, pour A en ordre croissant de valeur j'aurai :
A 00:00 15
A 03:00 16
A 02:00 35
A 06:00 41
A 01:00 52
A 04:00 65 <==
A 05:00 84
Je récupére l'avant dernière ligne. (65 étant le 2ème max). J'affiche donc A 04:00 65)

J'espère vraiment avoir été plus claire.
0
Re,

Ok, c'est plus clair.

Reste un bémol quand même.
Si on a deux valeurs pour le second max on choisi lequel?

Par exemple
A 00:00 15
A 03:00 16
A 02:00 65 <==
A 06:00 41
A 01:00 52
A 04:00 65 <==
A 05:00 84 

Il faudra peut être penser à utiliser un critère multiple de tri? Par heure par exemple.
0
wafa_o Messages postés 109 Date d'inscription mercredi 16 juillet 2008 Statut Membre Dernière intervention 4 janvier 2011 2
25 déc. 2009 à 19:25
A vrai dire, le cas ne s'est jamais présenté. Selon moi, il ne se produira pas.
0
Re,

En fait ça marche sans utiliser le tableau @t, un mais map-sort-map dans un contexte de liste et on affiche le deuxième élément.

lami20j@debian-vbox:/mnt/vbox/perl$ cat tri.pl 
#!/usr/bin/perl
use strict;use warnings;
my %h;
while(<DATA>){
  next if /^$/;
  my @t=split;
  push @{$h{$t[0]}}, join " ",@t[1..2];
}
for my $k(sort keys %h){
  print "$k ",
	(map  { $_->[0] } 
        sort { $b->[2] <=> $a->[2] } 
	map  { [$_, split ] } 
	@{$h{$k}})[1]
	,"\n";
}
__END__
A 00:00 15
A 01:00 52
A 02:00 35
A 03:00 16
A 04:00 65
A 05:00 84
A 06:00 41

B 00:00 45
B 01:00 16
B 02:00 98
B 03:00 102
B 04:00 10
B 05:00 9
B 06:00 43

C 00:00 12
C 01:00 85
C 02:00 35
C 03:00 17
C 04:00 66
C 05:00 48
C 06:00 26
0
wafa_o Messages postés 109 Date d'inscription mercredi 16 juillet 2008 Statut Membre Dernière intervention 4 janvier 2011 2
28 déc. 2009 à 09:35
Salut,

Merci. Je viens de tester et ca fonctionne parfaitement.
0