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 :

Gérer de l'aléatoire sur un hash de hash de tableaux


Sujet :

Langage Perl

  1. #1
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 603
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 603
    Par défaut Gérer de l'aléatoire sur un hash de hash de tableaux
    Coucou !!!

    Sur l'un de mes programmes, j'ai un hachage nommé %Phrase dont chaque clé est un hachage pointant vers un autre hachage. Le dernier hachage possède différentes valeurs sous forme de liste.

    Dans chaque liste, j'ai 12 phrases différentes et, pour les besoins d'un tiers programme, je pioche aléatoirement l'une des 12 phrases.

    Mon seul soucis, c'est que je suis obligé de faire un random sur une fourchette comprise entre 1 et 12 mais j'aimerais bien rajouter plein de phrases dans certaines clés. Aussi, le max du random ne serait plus 12 mais 18 ou 24 par exemple.

    Et c'est là mon soucis : je ne tiens absolument pas à gérer ces bibliothèques de phrases dont le nombre dépasserait 12 à part dans un autre random. Mais comment faire pour demander (sans que le temps d'exécution du programme n'en pâtisse) à Perl de faire du random sur la fourchette en descendant la borne supérieure de 1 s'il ne trouve pas de phrase à l'indice choisi par le random ?

    Je ne sais pas si c'est bien clair, c'est surtout pas évident à expliquer

    Qqun a une idée à m'exposer ?

    Edit : pour faire plus simple, admettons ce hachage là :

    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
    use strict;
     
    my %hash;
     
    $hash{TOTO}[0] = "une phrase";
    $hash{TOTO}[1] = "une phrase";
    $hash{TOTO}[2] = "une phrase";
    $hash{TOTO}[3] = "une phrase";
    $hash{TITI}[0] = "une phrase";
    $hash{TITI}[1] = "une phrase";
    $hash{TITI}[2] = "une phrase";
    $hash{TITI}[3] = "une phrase";
    $hash{TATA}[0] = "une phrase";
    $hash{TATA}[1] = "une phrase";
    $hash{TATA}[2] = "une phrase";
    $hash{TATA}[3] = "une phrase";
    $hash{TATA}[4] = "une phrase";
    $hash{TATA}[5] = "une phrase";
    $hash{TATA}[6] = "une phrase";
    $hash{TATA}[7] = "une phrase";
    Dans mon exemple, la borne supérieure maximale est 7 (0 pour la borne inférieure).

    A part faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $_ = rand(7);
    while(! defined($hash{ma_cle_recherchee}[$_]))
    {
        --$_;
    }
    print "$hash{ma_cle_recherchee}[$_]\n";
    Y a-t-il un autre moyen ?

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 603
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 603
    Par défaut
    A lire après avoir ingurgité le précédent post

    Pour rendre le truc un poil plus ardu, j'ai dit que mon hachage était un hachage de hachage de liste ? Exact, car je suis contraint de gérer selon le cas des phrases dont le contexte est au masculin OU au féminin.

    Si je reprend mon exemple ci-dessus, j'ai trés exactement ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $hash{TOTO}->{1}[0] = "une phrase au MASCULIN à l'indice 0";
    $hash{TOTO}->{2}[0] = "une phrase au FEMININ à l'indice 0";
    Sachant que bon nombre de phrases au féminin n'existent pas et que dans ce cas je me rabats sur la version masculine.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 76
    Par défaut
    Mes faibles connaissances m'ont posé pas mal de difficultée pour comprendre ton post.
    Un regard éxtérieur est toujours bénéfique je pense

    En gros tu voudrais savoir si il y a une autre maniére de faire plutot que de décrémenter le resultat de ton random jusqu'a obtenir un phrase ? ? en obtimisant le code

    Ou alors c'est cette operation du random que tu n'arrive pas a réaliser

  4. #4
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 603
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 603
    Par défaut
    Citation Envoyé par Gad29
    En gros tu voudrais savoir si il y a une autre maniére de faire plutot que de décrémenter le resultat de ton random jusqu'a obtenir un phrase ? ? en obtimisant le code
    C'est ça

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 76
    Par défaut
    Je m'excuse d'avance si mon idée peut paraitre dérisoire.

    Aurais tu penser a réaliser un hashaje (un de plus) qui aurait comme clé le nom de te liste et comme "contenu" le nombre de phrases cela te permetterais de changer en conséquant le nombre maximum du random.

    Aprés je ne sait pas dir si réaliser un tel hashaje serait plus lourd niveau éxécution du programme plutot que de décrémenter

  6. #6
    Expert confirmé
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Par défaut
    On peut toujours savoir combien d'éléments se trouve dans un tableau, @tableau en contexte scalaire donne le nombre d'éléments dans le tableau, donc rand(@tableau) donne un indice valide du tableau.
    Dans ton cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my $ind = rand(@{$hash{ma_cle_recherchee}});
     
    print "$hash{ma_cle_recherchee}[$ind]\n";
    --
    Jedaï

  7. #7
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 603
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 603
    Par défaut
    Citation Envoyé par Jedai
    On peut toujours savoir combien d'éléments se trouve dans un tableau, @tableau en contexte scalaire donne le nombre d'éléments dans le tableau, donc rand(@tableau) donne un indice valide du tableau.
    Dans ton cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my $ind = rand(@{$hash{ma_cle_recherchee}});
     
    print "$hash{ma_cle_recherchee}[$ind]\n";
    --
    Jedaï
    Et dans mon cas, si je dois printer une phrase féminine (si possible), je peux faire ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    my $ind = rand(@{$hash{TOTO}->{1}});
    if (defined ($hash{TOTO}->{2}[$ind]))
    {
        print "$hash{TOTO}->{2}[$ind]\n";
    }
    else
    {
        print "$hash{TOTO}->{1}[$ind]\n";
    }
    Purée, c'était si simple que ça m'est carrément passé sous le nez

    Heu, par contre, autre question : le programme qui s'amuse à traiter ces phrases en fait à la louche près de 20.000 à chaque fois qu'il est lancé. Est-ce que ça ne va pas le ralentir si le compilo est obligé à chaque fois de compter en interne le nbre d'éléments de chaque tableau ?

  8. #8
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 603
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 603
    Par défaut
    Citation Envoyé par Gad29
    Je m'excuse d'avance si mon idée peut paraitre dérisoire.

    Aurais tu penser a réaliser un hashaje (un de plus) qui aurait comme clé le nom de te liste et comme "contenu" le nombre de phrases cela te permetterais de changer en conséquant le nombre maximum du random.

    Aprés je ne sait pas dir si réaliser un tel hashaje serait plus lourd niveau éxécution du programme plutot que de décrémenter
    Tu n'as pas à t'excuser, ton idée n'est pas dérisoire et peut même être une piste à étudier en complément de ce que Jedai a écrit.



    PS : n'hésite pas à donner tes idées sur le forum. On a tous des niveaux de connaissance/maîtrise différents en Perl et puis ne t'inquiètes pas, Jedai a suffisamment à faire avec moi pour qu'il te laisse tranquille peinard dans ton coin

  9. #9
    Expert confirmé
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Par défaut
    Citation Envoyé par Arioch
    Heu, par contre, autre question : le programme qui s'amuse à traiter ces phrases en fait à la louche près de 20.000 à chaque fois qu'il est lancé. Est-ce que ça ne va pas le ralentir si le compilo est obligé à chaque fois de compter en interne le nbre d'éléments de chaque tableau ?
    A ma connaissance les tableaux en Perl connaissent leur taille à tout moment, ils n'ont pas besoin de la recalculer, elle est accessible directement dans leur structure de donnée. Donc pas de problème à mon avis.

    EDIT: Vérifié par un benchmark, pas de différence entre un tableau de 10 éléments et un tableau de 1000000 d'éléments, chez moi je peux demander la taille du tableau 75000000 fois par seconde... Ca devrait aller !

    --
    Jedaï

  10. #10
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 603
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 603
    Par défaut
    Citation Envoyé par Jedai
    A ma connaissance les tableaux en Perl connaissent leur taille à tout moment, ils n'ont pas besoin de la recalculer, elle est accessible directement dans leur structure de donnée. Donc pas de problème à mon avis.
    Ok, merci à tous !

  11. #11
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 603
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 603
    Par défaut
    Avec un peu de retard, j'ai mis ma modification dans mon code en me basant sur ce que Jedai préconise.

    Eh bien, ça ne marche pas comme escompté.

    Cette ligne là ne fonctionne pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $ind = rand(@{$hash{TOTO}->{1}});
    Message d'erreur généré : "TOTO" isn't valid argument.

    Celle-ci fonctionne parfaitement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $ind = rand(scalar(@{$hash{TOTO}->{1}}));
    Inutile de me demander si dans mon gros hash %hash, il existe ou non une clé "TOTO". La réponse est oui puisque le second cas fonctionne

    Par curiosité personnelle, j'aimerais comprendre pourquoi le contexte scalaire ne fonctionne pas pour le premier cas.

    Au cas où ça puisse aider celui ou celle qui répondra, le hash %hash se trouve dans un fichier externe au script Perl, un fichier .pm.

  12. #12
    Expert confirmé
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Par défaut
    A l'époque je n'avais pas vérifié parce que je pensais que rand() imposait un contexte scalaire à son argument... Mais vérification faite, rand() peut prendre 0 arguments, ce qui signifie que sans le scalar(), ton tableau se trouve en contexte de liste et donc s'applatit, d'où ton problème (tu as bien un TOTO dans le tableau ?).

    --
    Jedaï

  13. #13
    Membre averti
    Inscrit en
    Juillet 2003
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 15
    Par défaut
    Bonjour,
    Pour ma part je n'ai jamais eu la taille d'une liste avec @liste mais plutot $#liste... non ?

  14. #14
    Membre Expert
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 603
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 603
    Par défaut
    Citation Envoyé par zoulai
    Bonjour,
    Pour ma part je n'ai jamais eu la taille d'une liste avec @liste mais plutot $#liste... non ?
    Dans un contexte scalaire, @liste renvoie le nombre d'éléments qu'il contient.

  15. #15
    Expert confirmé
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Par défaut
    Citation Envoyé par zoulai
    Bonjour,
    Pour ma part je n'ai jamais eu la taille d'une liste avec @liste mais plutot $#liste... non ?
    $#liste renvoie le dernier indice de @liste, c'est à dire sa taille moins un.
    (J'utilise plutôt $#liste dans des boucles foreach où je suis obligé de passer par les indices plutôt que les éléments)

    --
    Jedaï

Discussions similaires

  1. Remplissage aléatoire sur Excel
    Par Trooper2 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 26/06/2006, 18h14
  2. Random aléatoire sur un tableau !
    Par sayajin dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 25/06/2006, 02h20
  3. Réponses: 2
    Dernier message: 09/02/2006, 16h17
  4. Réponses: 5
    Dernier message: 06/09/2005, 16h18
  5. Parcours d'un hash de hash de hash
    Par ngere dans le forum Langage
    Réponses: 5
    Dernier message: 06/07/2005, 09h53

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