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 :

clone de la fonction ispell


Sujet :

Langage Perl

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2013
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2013
    Messages : 6
    Points : 5
    Points
    5
    Par défaut clone de la fonction ispell
    salut,

    j'ai un petit exo en perl à faire pour ma 3e année de fac et je n'en viens pas à bout... j'ai un fichier 'dictionnaire' son rôle est je pense plutôt implicite, à savoir un mot par ligne.
    le but est de scanner un texte et proposer une correction orthographique des mots absents dans le dictionnaire par des mots qui diffèrent d'au plus de 2 caractères.


    voilà ce que j'ai fait pour le moment :

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    #! /usr/bin/perl
    use warnings;
    use strict;
     
     
     
    my $DICO_FNAME = "dictionnaire";
     
    sub word_exists {
      if (!defined($_[0])) {
        return 0;
      }
     
      open(DICO, "<", $DICO_FNAME);
      while(defined(my $word = <DICO>)) {
        if($word eq $_[0]) {
          return 1;
        }
      }
      close(DICO);
      return 0;
    }
     
    sub find_similar {
      if(!defined($_[0])) {
        return 0;
      }
     
      open(DICO, "<", $DICO_FNAME);
      my @words = ();
     
      while(defined(my $dword = <DICO>)) {
        if(length($dword) == length($_[0])) {
          my @string = split(//, $_[0]);
          my @chars = split(//, $dword);
          my $faults = 0;
     
          for my $char (@chars) {
            my $cp = shift(@string);
            if(defined($cp)) {
              if ($char ne $cp) {
                $faults++;
              }
            }
          }
          if($faults < 3) {
            push(@words, $dword);
          }
        }
      }
      return @words;
    }
     
    while(defined(my $word = <STDIN>)) {
      $word = lc($word);
      if(!word_exists($word)) {
        my @similis = find_similar($word);
        print "Corrections possibles : @similis\n";
      } else {
        chomp($word);
        print "$word : correct.\n";
      }
    }
    mais quand je lance
    rien ne se passe...

    je ne sais pas si j'ai bien expliqué mon problème en tout cas je remercie la communauté par avance
    bonne soirée

  2. #2
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    C'est très inefficace (moi je lirais le dictionnaire une fois pour toutes plutôt que deux fois par mot ) mais ça devrait fonctionner... Il est possible que les fins de lignes ne soient pas encodées de la même manière dans dictionnaire et dans STDIN (par exemple, l'un utilise \r\n, et l'autre seulement \n), ou qu'il y ait des espaces excédentaires dans les fichiers en tête ou fin de ligne. Pour te protéger contre cela élimine les fins de ligne lors de la lecture de dictionnaire et de STDIN, par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      while(defined(my $dword = <DICO>)) {
        $dword =~ s/[\r\n]*$//;
        ...
    De la même manière tu peux éliminer les espaces par
    Par ailleurs, tu forces le mot lu de STDIN en minuscules. Est-ce que le contenu du dictionnaire est en minuscules également ? Sinon ajoute également
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  3. #3
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Stocke les mots (en bas de casse, sans retours à la ligne) de ton dictionnaire dans un hash (comme clés du hash). Il suffit ensuite de tester si le mot existe dans le hash, ce qui considérablement plus rapide (potentiellement des milliers ou des dizaines de milliers de fois plus rapide, voire plus, selon la taille de ton dico

    Pour le recherche de mots "ressemblants, c'est plus compliqué. Une solution est d'établir un second hash (ou une structure de données plus complexe) avec les mots "normalisés" , par exemple avec les lettres des mots triés par ordre alphabétique ou en utilisant une forme de fonction de hachage sur les lettres. La longueur du mot est aussi utilisable comme discriminant partiel. Il est également possible de ne garder qu'un sous-ensemble des lettres pour accélérer la recherche. Bref autant de moyens d'obtenir assez rapidement une liste assez petite de candidats potentiels qu'il faut ensuite filtrer.

    Il faut sans doute commencer par écrire une fonction calculant la "distance" entre deux mots (plus ou moins de deux lettres d'écart).

  4. #4
    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 : 58
    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
    Points : 5 753
    Points
    5 753
    Par défaut
    Si tu as le droit d'utiliser des modules (j'en doute), une distance possible entre mots est la distance de Levenshtein accessible via le module Text::Levenshtein.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  5. #5
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2013
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2013
    Messages : 247
    Points : 406
    Points
    406
    Par défaut
    Sinon tu peux peut être stocker tes mots du dictionnaire sous la forme d'arbre et le parcourir quand tu n'as pas le mot-clé

    je suis pas très familier avec le concept mais je pense que ça peut être une approche

  6. #6
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Philou67430 Voir le message
    Si tu as le droit d'utiliser des modules (j'en doute), une distance possible entre mots est la distance de Levenshtein accessible via le module Text::Levenshtein.
    Il ne doit pas être trop compliqué d'implanter cette distance ou une version simplifiée pour le problème en question.

    Sinon, pour trouver des idées d'algorithmes, tu peux aussi consulter la littérature sur la distance de Hamming et les k-différences de Wu-Mamber.

  7. #7
    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 : 58
    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
    Points : 5 753
    Points
    5 753
    Par défaut
    Non, pas compliqué d'implémenter quelque chose, vu que dans le lien wikipédia, il y a déjà un algorithme
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

Discussions similaires

  1. La fonction clone() equivaut-elle à cela ?
    Par Invité dans le forum Débuter avec Java
    Réponses: 7
    Dernier message: 28/06/2013, 23h06
  2. La fonction clone supprime action sur un select
    Par lemirandais dans le forum jQuery
    Réponses: 8
    Dernier message: 25/04/2013, 21h42
  3. la fonction clone() et modification de l'objet cloné
    Par PP(Team) dans le forum jQuery
    Réponses: 0
    Dernier message: 10/08/2010, 09h31
  4. fonction clone() et formulaires dans un tableau
    Par FrankOVD dans le forum jQuery
    Réponses: 1
    Dernier message: 16/07/2010, 00h32
  5. Réponses: 6
    Dernier message: 22/06/2010, 10h00

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