Page 1 sur 4

Comment trouver des mot similaires parmi une liste

Publié : dim. 10/oct./2010 14:15
par dayvid
Salut,

Bon je cherche a améliorer mon logiciel "vérificateur d'orthographe"
j'aimerais faire une correction mais je ne sais pas comment je peut trouver des mot similaire
parmi une liste de mot
pour l'afficher dans un menu popup

Re: Comment trouver des mot similaires parmi une liste

Publié : dim. 10/oct./2010 15:33
par falsam
Similaires dans la prononciation ? Synonymes ?

Re: Comment trouver des mot similaires parmi une liste

Publié : dim. 10/oct./2010 16:26
par dayvid
j'en sais rien moi comme dans open office par exemple
ou tous autre correcteur d'orthographe

Re: Comment trouver des mot similaires parmi une liste

Publié : dim. 10/oct./2010 16:37
par Ar-S
des synonymes ?
dayvid a écrit :j'en sais rien moi comme dans open office par exemple
ou tous autre correcteur d'orthographe
ba si tu n'en sais rien...

Re: Comment trouver des mot similaires parmi une liste

Publié : dim. 10/oct./2010 17:18
par falsam
hihi j'avoue que tu es parfois surprenant dayvid :)

Tu vas devoir associé chaque mot de ton dictionnaire à une clé phonétique.

je te propose pour cela un exercice sur un algorithme phonétique d'indexation de noms par leur prononciation.

Toujours là ? :p

Soundex
L'objectif basique est que les noms ayant la même prononciation soient codés avec la même chaîne de manière à pouvoir trouver une correspondance entre eux malgré des différences mineures d'écriture.

Tu trouveras la description de cet algorithme en cliquant sur ce lien.

PS : Deux indices pour t'aider CreateRegularExpression et ReplaceRegularExpression.

Re: Comment trouver des mot similaires parmi une liste

Publié : dim. 10/oct./2010 19:45
par dayvid
hihi j'avoue que tu es parfois surprenant dayvid
Hein !!! quoi !!!, surprenant moi mais pourquoi :?

Wouoi, sa y est j'ai pété une durite :twisted:

J'ai raser mon stoque de neurones moi :lol:

Je tien a dire que j'ai crame mon disque dur (cerveau) en essayen de piger le truc
rien capter, trop compliquer je préfère me tire une balle :mrgreen:

Non aller HELP la car la j'y arriverais JAMAIS :cry:

Re: Comment trouver des mot similaires parmi une liste

Publié : lun. 11/oct./2010 16:42
par falsam
dayvid a écrit :Je tien a dire que j'ai crame mon disque dur (cerveau) en essayen de piger le truc
rien capter, trop compliquer je préfère me tire une balle :mrgreen:
Commences par créer une base de données. (SQLite ira très bien. Regarde l'aide)
Ex : CreateFile(#dico_db,"dico.db3")

Crées ensuite une table dont chaque ligne contient le mot de ton dictionnaire et la codification Soundex suivant la requête ci-dessous.
"Create Table DicoFR (Word Char(30), SoundexCode Char(10))"

Associe une clé champ qui contient la codification SoundEx suivant la requête ci-dessous.
"Create Index SoundexKey On DicoFr(SoundexCode ASC)"


Crées ensuite une boucle qui lit en entrée ton dictionnaire sous forme de fichier texte et qui transfère chacune des lignes dans la base de donnée SQLite aprés avoir calculer la codification SoundEx.
Le traitement est assez long car ton dictionnaire doit contenir environ 63000 mots.

dayvid a écrit :Non aller HELP la car la j'y arriverais JAMAIS :cry:
N'en dit pas plus, tu trouveras le code que tu placeras dans un fichier include.

Code : Tout sélectionner

; Soundex Version 1.00
; Contributor : Falsam

;Soundex est un algorithme phonétique d'indexation de noms par leurs consonances 

;L'objectif basique est que les noms ayant la même prononciation 
;soient codés avec la même chaîne de manière à pouvoir trouver 
;une correspondance entre eux malgré des différences mineures d'écriture. 

;L'algorithme procède comme suit :
;Supprimer les éventuels 'espace' initiaux
;Mettre le mot en majuscule
;Garder la première lettre
;Conserver la première lettre de la chaîne.
;Supprimer toutes les occurrences des lettres : a, e, h, i, o, u, w, y (à moins que ce ne soit la première lettre du nom)
;Attribuer une valeur numérique aux lettres restantes de la manière suivante :

;Version pour l'anglais :
;1 = B, F, P, V
;2 = C, G, J, K, Q, S, X, Z
;3 = D, T
;4 = L
;5 = M, N
;6 = R

;Version pour le français :(Par defaut)
;1 = B, P
;2 = C, K, Q
;3 = D, T
;4 = L
;5 = M, N
;6 = R
;7 = G, J
;8 = X, Z, S
;9 = F, V

;Si deux lettres (ou plus) avec le même nombre sont adjacentes dans le nom d'origine, 

;Renvoyer les quatre premiers octets complétés par des zéros.

;En effectuant cet algorithme, on obtient avec "Robert" et "Rupert" la même chaîne : "R163", tandis que "Rubin" donne "R150".

Enumeration
  #Buffer
  #RegExpr  
EndEnumeration

Global FirstLetter.s ;Récupération de la 1er lettre du mot
Global xBuffer.s     ;Copie du mot en cours de lecture avant dédoublonnage des lettres consécutives 
Global i.l                ;Indice de parcours du mot en cours de dédoublonnage.


Procedure.s Soundex(Buffer.s)
  FirstLetter="" : xBuffer="" : i=0
  
  ;Supprimer les espaces
  Buffer = ReplaceString(Buffer, " ", "")
    
  ;Mettre en majusule
  Buffer = UCase(Buffer)

  ;Garder la premiere lettre
  FirstLetter = Left(Buffer, 1)
  Buffer=Right(Buffer,Len(Buffer)-1)
  
  ;Elimination des voyelles A,E,I,O,U,Y ainsi que H et W
  CreateRegularExpression(#Buffer,"[A,E,I,O,U,Y,H,W,Â,Ä,À,È,É,Ê,Ë,Œ,Î,Ï,Ô,Ö,Ù,Û,Ü]")
  Buffer=ReplaceRegularExpression(#Buffer,Buffer,"")
  
  
  ;Remplacer les lettres restantes par le chiffre associé (Code francophone)
  
  ;Remplacement de B, P par 1
  CreateRegularExpression(#RegExpr,"[B,P]")
  Buffer=ReplaceRegularExpression(#RegExpr,Buffer,"1")
  
  ;Remplacement de C, K, Q par 2
  CreateRegularExpression(#RegExpr,"[C,K,Q]")
  Buffer=ReplaceRegularExpression(#RegExpr,Buffer,"2")
  
  ;Remplacement de D, T par 3
  CreateRegularExpression(#RegExpr,"[D,T]")
  Buffer=ReplaceRegularExpression(#RegExpr,Buffer,"3")
  
  ;Remplacement de L par 4
  CreateRegularExpression(#RegExpr,"[L]")
  Buffer=ReplaceRegularExpression(#RegExpr,Buffer,"4")
  
  ;Remplacement de M, N par 5
  CreateRegularExpression(#RegExpr,"[M,N,]")
  Buffer=ReplaceRegularExpression(#RegExpr,Buffer,"5")
  
  ;Remplacement de R par 6
  CreateRegularExpression(#RegExpr,"[R]")
  Buffer=ReplaceRegularExpression(#RegExpr,Buffer,"6")
  
  ;Remplacement de G, J par 7
  CreateRegularExpression(#RegExpr,"[G,J]")
  Buffer=ReplaceRegularExpression(#RegExpr,Buffer,"7")
  
  ;Remplacement de S, X, Z par 8 (Le Ç devient aussi un S)
  CreateRegularExpression(#RegExpr,"[Ç,S,X,Z]")
  Buffer=ReplaceRegularExpression(#RegExpr,Buffer,"8")
  
  ;Remplacement de F, V par 9
  CreateRegularExpression(#RegExpr,"[F,V]")
  Buffer=ReplaceRegularExpression(#RegExpr,Buffer,"9")
  
  ;Supprimer les chiffres répétés (garder une seule occurence : 11 devient 1, 22 devient 2, etc ....)
  For i=1 To Len(Buffer) 
      car.s=Mid(Buffer,i,1)
      If FindString(xBuffer,Mid(Buffer,i,1),1)=0 
         xBuffer=xBuffer+car
      EndIf   
   Next i
   Buffer=xBuffer  
   
  ;Renvoyer les quatre premiers octets complétés par des zéros.
  ProcedureReturn LSet(FirstLetter+Buffer,4,"0")
EndProcedure
J’espère que je ne me suis pas planté !!

Re: Comment trouver des mot similaires parmi une liste

Publié : lun. 11/oct./2010 16:49
par falsam
Ton programme final est tout simple.

Un écran principal qui contient un champ de saisie et une liste de résultat dans lequel tu pourras sélectionner ton mot.

Chaque fois que tu saisies un nouveau mot tu auras le résultat dans ta liste en temps réel suivant la requête suivante. Lance la requête après avoir saisi au moins 2 lettres.
select Word from dicoFr where SoundexCode="+Chr(39)+soundex(GetGadgetText(#Edit))+Chr(39)

Sélectionne ensuite le mot dans ta liste de résultat que tu placera dans ton champ de saisie.

Re: Comment trouver des mot similaires parmi une liste

Publié : lun. 11/oct./2010 16:56
par Backup
intéressant comme algo :)

ajouter "ç" dans les "s" ;)

Re: Comment trouver des mot similaires parmi une liste

Publié : lun. 11/oct./2010 17:01
par falsam
Intéressant mais sachant que le code retourné est sur 4 octets est ce vraiment efficace ?
/me part à la recherche d'un dico au format txt pour expérimenter la chose

PS : La fonction SoundEx existe aussi en Php

Re: Comment trouver des mot similaires parmi une liste

Publié : lun. 11/oct./2010 17:10
par dayvid
waou !

Je vais étudier sa de près
GRAND MERCI A TOI FALSAM :D

Re: Comment trouver des mot similaires parmi une liste

Publié : lun. 11/oct./2010 17:58
par falsam
Un dictionnaire sur ce lien http://www.pps.jussieu.fr/~dicosmo/IUP/ ... ccents-iso

Ctrl+A pour tout sélectionner puis Ctrl+C pour tout copier. (je me demande pourquoi je dis ça)

Et je copie le tout dans un fichier que je nomme dico.txt

Re: Comment trouver des mot similaires parmi une liste

Publié : lun. 11/oct./2010 18:00
par falsam
Création de la base de données

Code : Tout sélectionner

IncludeFile "soundex.pb"
UseSQLiteDatabase()

Enumeration
  #dico_txt  ;Le dictionnaire au format texte
  #dico_db  ;La base de données SQlite3
  #dico_tab ;la table des mots 
EndEnumeration

SqlQuery.s   ;Requéte SQL
Word.s        ;Mot en cours de lecture 

;Creation de la base de données 
If CreateFile(#dico_db,"dico.db3")
  CloseFile(#dico_db)
EndIf

;Connection à la base de données
If OpenDatabase(#dico_db, #PB_Compiler_FilePath+"/dico.db3", "", "", #PB_Database_SQLite)
  
  ;Création de la table dictionnaire
  SqlQuery="Create Table DicoFR (Word Char(30), SoundexCode Char(10))"
  DatabaseUpdate(#dico_db,SqlQuery)
  
  SqlQuery="Create Index SoundexKey On DicoFr(SoundexCode ASC)"
  DatabaseUpdate(#dico_db,SqlQuery)
  
  ;Lecture du fichier texte contenant les mots à enregistrer dans la base de données
  If ReadFile(#dico_txt,"Dico.txt")
    ;Tant que la fin du fichier n'est pas atteint
    While Eof(#dico_txt)=0
      
      ;Lecture du mot suivant 
      word=ReadString(#dico_txt)
      
      ;Mise en forme de la requete d'ajout dans la base de données 
      SqlQuery = "insert into dicoFR (Word, SoundexCode) values ('"
      SqlQuery + Word + "','"
      SqlQuery + Soundex(Word) + "') "
      
      ;Enregistrement du mot dans la base de données.  
      Debug "Insertion de "+Word
      DatabaseUpdate(#dico_db,SqlQuery)
     Wend
     CloseFile(#dico_txt)
     MessageRequester("Information","Fin du traitement")
   EndIf
EndIf
 
Le traitement est long (Au moment ou je poste ce message, ce n'est pas terminé)

Re: Comment trouver des mot similaires parmi une liste

Publié : lun. 11/oct./2010 18:03
par falsam
la création de la base est toujours en cours, mais la recherche de mot peut quand meme fonctionner.
le programme est minimaliste :p

Code : Tout sélectionner

IncludeFile "soundex.pb"

UseSQLiteDatabase()

Enumeration 
  #FontApp    ;Police de caractére globale de l'application
  #Dico         ;Base de donnée SqLite
  #MainForm  ;La fenetre de saisie 
  #Edit          ;avec son champs de saisie 
  #ListeResult;et sa liste de résultat 
EndEnumeration


;Affichage de l'ecran principale
Procedure MainFormSHow()
  LoadFont(#FontApp,"Arial",10)
  SetGadgetFont(#PB_Default,FontID(#FontApp)) 
  If OpenWindow(#Mainform,0,0,500,400,"Recherche d'un mot", #PB_Window_ScreenCentered | #PB_Window_SystemMenu )
    StringGadget(#edit,20,50,200,22,"")
    ListViewGadget(#ListeResult,35,80,200,200)
    HideGadget(#ListeResult,1)
    SetActiveGadget(#Edit)
  EndIf
EndProcedure

;Cherchons la liste de mot ayant en commun le meme code SoundEx
;le mot recherché doit au moins avoir 2 lettres 
Procedure SearchWord() 
  ReqSql.s="select Word from dicoFr where SoundexCode="+Chr(39)+soundex(GetGadgetText(#Edit))+Chr(39)
  
  If Len(GetGadgetText(#Edit))>2
    If OpenDatabase(#Dico, #PB_Compiler_FilePath+"/dico.db3", "", "", #PB_Database_SQLite)
      If DatabaseQuery(#Dico, ReqSql)
        ClearGadgetItems(#ListeResult)
        HideGadget(#ListeResult,0)
        While NextDatabaseRow(#Dico)
          AddGadgetItem(#ListeResult,-1,GetDatabaseString(#Dico, 0))
        Wend
        FinishDatabaseQuery(#Dico)
      Else
        MessageRequester("Erreur", "Impossible d'executer la requete: "+DatabaseError())
      EndIf
      CloseDatabase(#Dico)
    EndIf
  Else
    HideGadget(#ListeResult,1)
  EndIf
EndProcedure

MainFormSHow()

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_Gadget
      Select EventGadget()
          
        Case #ListeResult
          SetGadgetText(#Edit, GetGadgetText(#ListeResult))
          SetActiveGadget(#Edit)
          HideGadget(#ListeResult,1)
          
        Case #Edit
          Select EventType()
            Case #PB_EventType_Focus
            Case #PB_EventType_Change
              SearchWord()
          EndSelect 
      EndSelect
    
                
    Case #PB_Event_CloseWindow
      End
      
  EndSelect
ForEver

Re: Comment trouver des mot similaires parmi une liste

Publié : lun. 11/oct./2010 18:41
par Warkering
My god, Falsam, t'es une bombe à PB! :mrgreen:
Merci pour le dico! :wink: