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 :

array et comparaison de valeurs


Sujet :

Langage Perl

  1. #1
    Membre éprouvé
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Par défaut array et comparaison de valeurs
    j'ai un array et j'aimerais afficher les x plus grandes valeurs et garder les indices associés ... quelle est la façon la + simple de faire? Merci

  2. #2
    Responsable Perl et Outils

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 822
    Par défaut
    Tu reprends l'algo traité ici.

  3. #3
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2011
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 184
    Par défaut
    Tu crées un tableau T de X cases dans lequel tu stockeras, de manière ordonnée, les indices des X plus grandes valeurs de ta liste L.

    Tu parcours ta liste élément par élément et tu insères l'indice de l'élément courant E dans T si T n'est pas rempli.
    Si T est plein, tu compares E à L(T(0)). Si E est plus grand, tu supprimes T(0) et tu insères l'indice de E à sa place dans T.

    Si ça peut attendre quelques minutes, j'essaierai de te donner un bout de code.

  4. #4
    Membre éprouvé
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Par défaut merci
    merci, j'obtiens ainsi la valeur maximum et son indice mais si je veux les 5 premières valeurs maximales

    ex : 564, 469, 456, 400, 365


    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
    #!/usr/bin/perl
    use warnings;
    use strict;
     
     
     
    my @test = qw/ 1 6  2 365 4 0 06 6 8 76 055 46 0 065 456 40 -5  95 4 05 400 564  4 469 6/;
     
    # rechercher les indexs des 5 valeurs les + élevées
    my $nb = 5;
     
    my ($index, $max);
     
    for my $i ( 0..$#test ) {
     
      if ( ( defined $max and $test[$i] > $max ) || not defined $max ) { 
     
        $index = $i; 
        $max = $test[$i]; 
     
      }
     
    }
    print "Index : $index, Max : $max\n";

    comment adapter pour obtenir ces 5 valeurs et leur indice?

  5. #5
    Membre éprouvé
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Par défaut
    Citation Envoyé par Dimitry.e Voir le message
    Tu crées un tableau T de X cases dans lequel tu stockeras, de manière ordonnée, les indices des X plus grandes valeurs de ta liste L.

    Tu parcours ta liste élément par élément et tu insères l'indice de l'élément courant E dans T si T n'est pas rempli.
    Si T est plein, tu compares E à L(T(0)). Si E est plus grand, tu supprimes T(0) et tu insères l'indice de E à sa place dans T.

    Si ça peut attendre quelques minutes, j'essaierai de te donner un bout de code.

    merci, c'est très sympa ça a le temps, c'est pour demain. Je m'y remettrai à 7h00 en arrivant au boulot. Bonne après-midi.

  6. #6
    Membre éprouvé
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Par défaut j'avais pensé à qqch comme ça
    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
    #!/usr/bin/perl
     
    use warnings;
    use strict;
     
        use List::MoreUtils qw{    indexes    }; 
     
    my @array_score = qw/ 1 6  2 365 4 0 06 6 8 76 055 46 0 065 456 40 -5  95 4 05 400 564  4 469 6/;
     
    # rechercher les indexs des 5 valeurs les + élevées
    my $nb = 5;
     
     
    # tableau contenant les indices classés de @array_score
    my @liste_t;
     
    for (0..$#array_score){
     
    	# on recherche l'indice ayant la valeur la + élevée de @array_score
    	my @x = indexes { $_ == (sort {$b<=>$a} @array_score )[0]  } @array_score ;
     
    	# on place la valeur de l'indice dans @liste_t
    	push @liste_t, $x[0],
     
    	# on supprime la valeur de @array_score
    	delete $array_score[$x[0]];
     
     
    }
    mais à ça ne va pas

  7. #7
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2011
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 184
    Par défaut
    Il y a certainement mieux, mais voilà une solution :
    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
     
    use strict;
    use warnings;
     
    my @t = qw/ 1 6  2 365 4 0 06 6 8 76 055 46 0 065 456 40 -5  95 4 05 400 564  4 469 6/;
    my $N = 5;
     
    #Stocker les indices des N premieres valeurs
    my @max = (0..$N-1);
     
    #Trier les indices en fonction des valeurs correspondantes dans t
    @max = sort({$t[$a]<=>$t[$b]} @max);
     
    #Recherche de valeurs plus grandes dans le reste du tableau
    my $i = 5;
    while ($i<scalar(@t)) {
      #Si la valeur pointee par i est plus grande que les 5 retenues
      if($t[$i] > $t[$max[0]]) {
        $max[0] = $i; # Ajouter son indice a la liste
        @max = sort({$t[$a]<=>$t[$b]} @max); # Placer le nouvel indice au bon endroit
      }
      ++$i;
    }
     
    foreach my $m (@max) {
      print $t[$m]."\n";
    }

  8. #8
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    L'algorithme de dimitry me semble pas mal :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    @index = ();
    my @array_score = qw/ 1 6  2 365 4 0 06 6 8 76 055 46 0 065 456 40 -5  95 4 05 400 564  4 469 6/;
     
    foreach my $score (0 .. $#array_score) {
      @index = (sort { $array_score[$b] <=> $array_score[$a] } grep defined, @index, $score)[0.. 4];
    }
     
    print map "$array_score[$_] (indice $_)\n", @index;
    Le sort n'est pas aussi efficace qu'une recherche linéaire pour savoir quel élément éjecter, mais sur une taille de 5 éléments et avec une liste toujours presqu'entièrement déjà triée, la perte d'efficacité aura une incidence assez faible.

    Edit : grillé (de peu )

  9. #9
    Responsable Perl et Outils

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 822
    Par défaut
    Voilou
    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
    #!/usr/bin/perl
    use warnings;
    use strict;
    use List::MoreUtils qw{    uniq    }; 
     
    my @test = qw/ 1 6  2 365 4 0 06 6 8 76 055 46 0 065 456 40 -5  95 4 05 400 564  4 469 6/;
    my %values_index;
    my $recherche_x_plus_grande_valeur = 5;
     
    foreach my $valeur ( reverse sort { $a <=> $b } uniq @test ) {
      $values_index{$valeur} = undef;
      $recherche_x_plus_grande_valeur--;
      last if ( $recherche_x_plus_grande_valeur == 0 );
    }
     
     
    for my $i ( 0..$#test ) {
      if ( exists $values_index{ $test[$i] } ) { 
        print "Index : $i, value : $test[$i]\n";
        delete $values_index{ $test[$i] };
        last if ( scalar keys %values_index == 0 ); 
      }
    }

  10. #10
    Responsable Perl et Outils

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 822
    Par défaut
    Edit: grillé par les 2

  11. #11
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2011
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 184
    Par défaut
    Je me disais bien que j'avais déjà fait ça dans ma période "ça tient sur deux lignes en perl" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    my @t = qw/ 1 6  2 365 4 0 06 6 8 76 055 46 0 065 456 40 -5  95 4 05 400 564  4 469 6/;
    my $N = 5;
    @max = (sort({$t[$a]<=>$t[$b]} (0..$#t)))[scalar(@t)-$N..$#t];

  12. #12
    Membre éprouvé
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Par défaut merciiiiiiiiii
    un grand merci pour vos réponses, c'est vraiment très sympa de votre part.

  13. #13
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    Citation Envoyé par Dimitry.e Voir le message
    Je me disais bien que j'avais déjà fait ça dans ma période "ça tient sur deux lignes en perl" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    my @t = qw/ 1 6  2 365 4 0 06 6 8 76 055 46 0 065 456 40 -5  95 4 05 400 564  4 469 6/;
    my $N = 5;
    @max = (sort({$t[$a]<=>$t[$b]} (0..$#t)))[scalar(@t)-$N..$#t];
    Effectivement, le plus court est naturellement de faire un sort sur TOUT le tableau (tester l'efficacité de l'algo sur de gros tableaux par rapport à ton algo proposé initialement, qui est moins complexe).

    Sinon, tu peux encore encore réduire ta ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @max = (sort({$t[$b]<=>$t[$a]} (0..$#t)))[0..$N-1]; # tri inverse
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @max = (sort({$t[$a]<=>$t[$b]} (0..$#t)))[-$N..-1];

  14. #14
    Responsable Perl et Outils

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

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 822
    Par défaut
    Citation Envoyé par Philou67430 Voir le message
    Effectivement, le plus court est naturellement de faire un sort sur TOUT le tableau (tester l'efficacité de l'algo sur de gros tableaux par rapport à ton algo proposé initialement, qui est moins complexe).

    Sinon, tu peux encore encore réduire ta ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @max = (sort({$t[$b]<=>$t[$a]} (0..$#t)))[0..$N-1]; # tri inverse
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @max = (sort({$t[$a]<=>$t[$b]} (0..$#t)))[-$N..-1];
    Pour faire le trie inverse, il faut utiliser reverse au lieu de $b <=> $a. C'est plus optimum !!

  15. #15
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    Euh... relis djibril... c'est ce que j'ai fais (mais comme le demandais Jasmine, c'est fait sur le tri des indices, pas sur celui des valeurs)

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

Discussions similaires

  1. GTK+ comparaison entier valeur du pointeur
    Par Emyleet dans le forum GTK+ avec C & C++
    Réponses: 10
    Dernier message: 21/07/2006, 16h28
  2. comparaison de valeur sur un résultat de requete
    Par griese dans le forum Langage
    Réponses: 5
    Dernier message: 28/06/2006, 16h23
  3. comparaison de valeurs
    Par Flobynaldo dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 17/05/2006, 17h56
  4. Comparaison de valeurs stockees dans un meme champ
    Par Tartenpion dans le forum Langage SQL
    Réponses: 4
    Dernier message: 15/02/2006, 22h33
  5. Réponses: 3
    Dernier message: 14/12/2005, 16h17

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