begin process at 2010 03 19 19:12:49
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Texte

 > TROUVER TOUS LES ANAGRAMMES D'UN MOT (AVEC DICO)

TROUVER TOUS LES ANAGRAMMES D'UN MOT (AVEC DICO)


 Information sur la source

Note :
5,5 / 10 - par 2 personnes
5,50 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Texte Classé sous :anagramme, anagrammeur, dictionnaire, dico, mot Niveau :Initié Date de création :30/08/2005 Date de mise à jour :30/08/2005 20:33:53 Vu / téléchargé :96 619 / 1 116

Auteur : Abened

Ecrire un message privé
Site perso
Commentaire sur cette source (11)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Pour l'exe et le dico (trop lourd pour le site), telecharger http://perso.club-internet.fr/jbe/anagrammes.zip

Ben comme annoncé dans le titre de la source ce programme a pour but de vous faire devenir imbattable dans la résolution d'anagrammes (sans avoir à se prendre la tete inutilement ;-D ).
On commence par charger un dico : j'en ai trouvé un de 146.000 mots gratuitement il y a longtemps, je remercie chaleuresement le ptit gars qui a ecrit tout ca (même si certains mots n'existent pas et que d'autre ne font pas partie du dico c'est deja une bonne base !).
Tout le prog repose sur la notion d'arbres : chaque node (noeud) de l'arbre du dico represente une lettre et les leafs (feuilles) sont les mots finaux (ils representent le mot obtenu en alignant toutes les lettres des parents dans l'ordre de parenté). Une fois cette arbre construit (ce qui n'est pas tres long malgré la masse de travail), on peut commencer la recherche d'anagramme a proprement parler.
Encore une fois, c'est un arbre qui fait tout le travail : chaque node possede un champ Text qui contient toutes les lettres de l'anagramme pas encore utilisée dans cette partie de l'arbre, et donc chaque node crée un enfant par lettre pas encore utilisée pour lequel le champ Text ne contient plus une de ces lettres. (J'ai bien peur de n'etre clair que pour moi meme... :-S).

Mais bon, contruire tout l'arbre des anagramme, c'est long (le nombre du mot est en n!, avec n la longueur), et verifier si chaque mot qui en resulte appartient au dico, ca l'est encore plus ! C'est pourquoi on met a parti les arbres pour nous accelerer le boulot : l'info c'est comme la botanique, le but c'est de bien tailler les arbres :D => Les elements de l'arbre des anagramme conserve un pointeur vers le mot du dico correspondant, et dès qu'on s'apercoit qu'il n'existe aucun mot du dico possible avec les combinaisons commencées on ne continue pas a creer l'arbre. Exemple : j'entre l'anagramme TRUCS. On commencer a creer l'arbre et en s'apercevant qu'aucun mot ne commence par TC ou CT ou meme RC on elague pas mal la chose...

Voila j'espere avoir réussi a expliquer a peu pres le principe et vous permettre de bientot briller en societé :)

Source

  • Je met juste la déclaration des differents objets des arbres pour avoir une idée du code
  • type //DICTIONNAIRE
  • TDicoNodeStyle = (nsDicoNode,nsDicoLeaf);
  • PDicoNode = ^TDicoNode;
  • TDicoNode = class(TObject)
  • private
  • public
  • Parent : PDicoNode;
  • Level : integer;
  • Child : array[0..26] of TDicoNode;
  • ChildCount : integer;
  • Style : TDicoNodeStyle;
  • Letter : integer;
  • Text : string;
  • procedure AddWord(str: string);
  • constructor Create(str : string; c : integer; Par : PDicoNode); virtual;
  • destructor Destroy; override;
  • end;
  • type //ANAGRAMMES
  • TAnaNodeStyle = (nsNode,nsLeaf,nsNone);
  • PAnaNode = ^TAnaNode;
  • TAnaNodeList = class;
  • TAnaNode = class(TObject)
  • private
  • public
  • Parent : PAnaNode;
  • PDico : PDicoNode;
  • Child : TAnaNodeList;
  • Level : integer;
  • Style : TAnaNodeStyle;
  • Letter : char;
  • Text : string;
  • constructor Create(str : string; c : char; Par : PAnaNode; PDic : PDicoNode); virtual;
  • destructor Destroy; override;
  • end;
  • TAnaNodeList = class(TObjectList)
  • private
  • function GetItem(Index: Integer): TAnaNode;
  • procedure SetItem(Index: Integer; const Value: TAnaNode);
  • public
  • property Items[Index: Integer]: TAnaNode read GetItem write SetItem; default;
  • end;
Je met juste la déclaration des differents objets des arbres pour avoir une idée du code

type  //DICTIONNAIRE
  TDicoNodeStyle = (nsDicoNode,nsDicoLeaf);
  PDicoNode = ^TDicoNode;

  TDicoNode = class(TObject)
  private

  public
    Parent : PDicoNode;
    Level : integer;
    Child : array[0..26] of TDicoNode;
    ChildCount : integer;
    Style : TDicoNodeStyle;
    Letter : integer;
    Text : string;
    procedure AddWord(str: string);
    constructor Create(str : string; c : integer; Par : PDicoNode); virtual;
    destructor Destroy; override;
  end;

type  //ANAGRAMMES
  TAnaNodeStyle = (nsNode,nsLeaf,nsNone);
  PAnaNode = ^TAnaNode;

  TAnaNodeList = class;

  TAnaNode = class(TObject)
  private
  
  public
    Parent : PAnaNode;
    PDico : PDicoNode;
    Child : TAnaNodeList;
    Level : integer;
    Style : TAnaNodeStyle;
    Letter : char;
    Text : string;
    constructor Create(str : string; c : char; Par : PAnaNode; PDic : PDicoNode); virtual;
    destructor Destroy; override;
  end;

  TAnaNodeList = class(TObjectList)
  private
    function GetItem(Index: Integer): TAnaNode;
    procedure SetItem(Index: Integer; const Value: TAnaNode);
  public
    property Items[Index: Integer]: TAnaNode read GetItem write SetItem; default;
  end;

 Conclusion

J'ai remarqué la présence de doublons lorsqu'un mot contient plusieurs fois la meme lettre, et je vais essayer d'y remedier bientot (mais je chercher encore un moyen efficace de le faire, si vous avez une idée je suis preneur...). Sinon evitez juste d'entrer n'importe quoi dans le champ de texte (les lettres suffisent :P).

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

30 août 2005 01:02:10 :
Remise en forme du texte de présentation...
30 août 2005 01:03:45 :
Encore une mise en forme
30 août 2005 20:33:53 :
Modification conseillée par Debiars pour ne pas afficher les résultats en double.

 Sources du même auteur

Source avec Zip SNAKE PC

 Sources de la même categorie

Source avec Zip COMBINAISONS DE STRINGS par askil2000
Source avec Zip Source avec une capture RECONNAISSANCE DE CARACTÈRES (OCR) par Bacterius
Source avec Zip Source avec une capture NETTOYAGE AUTOMATIQUE DE NOMS DE FICHIERS par John Dogget
DISTANCE DE JARO-WINKLER par PoulpHunter
Source avec Zip BASE DE DONNÉE WIKI par thithony

 Sources en rapport avec celle ci

Source avec Zip DICTIONNAIRE DE RIMES par L_art_ment
Source avec Zip BASE DE DONNÉE WIKI par thithony
Source avec Zip Source avec une capture DICO ET AIDE MOTS CROISÉE par thithony
Source avec Zip Source avec une capture DICTIONNAIRE DE MOTS OSD (WOLOF) par julesouley
Source avec Zip Source avec une capture DICTIONNAIRE DE MOTS OSD (FRANCAIS) par julesouley

Commentaires et avis

Commentaire de Debiars le 30/08/2005 16:59:13

Bonjour Abened,
Pour éviter d'afficher les doublons, une petite procédure toute simple pour vérifier s'il ne figure pas déjà dans la liste :

procedure AfficheMot(str : string);
var i : integer;
begin
  for i := 0 to form1.lbResult.Items.Count-1 do
    if str = form1.lbResult.Items[i] then Exit;
  form1.lbResult.Items.Add(str);
end;

procedure RecurMot(Node : TAnaNode; str : string);
var i : integer;
begin
  if Node.Level>0 then str:=str+Node.Letter;
  if Node.Style=nsLeaf then AfficheMot(str)  // ligne modifiée

bye :-D

Commentaire de Abened le 30/08/2005 20:27:20

Effectivement Debiars, c'est une solution simple a mettre en oeuvre pour eviter *d'afficher* les doublons, mais cela n'empeche pas que dans l'arbre, il y a 2 (ou plutot 2^(nombre de lettre en double) ) braches de l'arbre qui sont developpées et pourtant identiques, et c'est a ce niveau la que j'aurais aimé optimiser mon code (même si je n'ai jamais dépassé 30ms pour trouver un anagramme, on a pratiquement l'impression qu'il ne fait rien :D). Pour le moment je vais integrer ca au code quand meme.
Merci du commentaire :) Abened

Commentaire de yvemoreau le 03/09/2005 18:41:06

bonjour, j'ai trouvé un code sur le site en vb je crois et je l'ai traduis pour l'utiliser dans ton prog...j'ai bidouillé ton code pas mal pour le simplifié car je n'arrivais pas à créer toutes les possibilités .

Creer_Poss(UpperCase(edText.Text),1,length(edText.Text),'');
renvoi dans une TStringList toutes les possibilités...


procedure Creer_Poss(Mot:String;n:Integer;lg:Integer;nouveauMot:String);
var
     temp:String;
     i,j,k,m:Integer;
begin
   if(lg<>0)then
   begin
      for i:=1 to lg do
      begin
         setlength(nouveauMot,n);
         nouveauMot[n]:=Mot[i];
         temp:='';
         for m:=1 to n do temp:=temp+nouveauMot[m];

         //if(Dico(temp)=true)then
         strList.Add(temp);

         k:=1;
         for j:=1 to lg do
         begin
            if(j<>i)then
            begin
               setlength(temp,k);
               temp[k] := Mot[j];
               inc(k);
            end;
         end;
         Creer_Poss(temp, n+1, lg-1, nouveauMot);
      end;
   end;
end;

Commentaire de yvemoreau le 07/09/2005 23:19:39

Rebonjour ,

j'ai bidouillé encore car ce truc m'intéresse énormément et à force de tourner en rond avec ces possibilités ,j'ai creer un autre arbre en limitant les nodes à celles de l'anagramme puis j'ai cliqué ...Je parcours maintenant le dico qu'une seule fois node par node ,si c'est impossible je saute à la branche suivante ,et en prime j'obtiens classer en ordre alphabétique une liste sans doublons ...

Le temps de recherche pour "anticonstitutionnellements" n.est pas plus long que la création du dico !!!

1er filtre en parcourant le dico:
var
MySet: set of 'A'..'Z';

MySet :=[];
   for x:=0 to length(ANAGRAMME)do
   begin
      if not (ANAGRAMME[x+1] in MySet)then
      MySet :=MySet + [ANAGRAMME[x+1]];
   end;


et en parcourant le dico je teste :

if not(T^.Lettre in MySet )then break;
se qui conduit à la branche suivante...

le deuxiemme filtre, là, j'ai pas trouvé mieux :
je compare les lettres de l'anagramme avec les lettres
du mot en mémoire...

Function Compare(Mot:String;ANA:String):Boolean;
var
a,b:Integer;
begin
   result:=false;
   for b:=length(Mot) downto 1 do
   begin
      for a:=1 to length(ANA)do
      begin
         if (mot[b]=ANA[a])then
         begin
            setlength(mot,length(Mot)-1);
//pour une fois que le downto est utile
            ANA[a]:='?';
//pour dire qu'utiliser
            break;
         end;
      end;

      if(mot='')then
      begin
         result:=true;
         exit;
      end;
   end;
end;


ps:vérifie ton dico certains mots ont plus de 27 lettres
et sont en doubles...

Pour le code au complet comme le mérite te reviens je te l'envoi quand tu voudras ...

pour les autres on verra , lol ...
Yve

Commentaire de BruNews le 07/09/2005 23:52:51 administrateur CS

Si tu veux récupérer des mots, tu peux te servir ici:
http://www.cppfrance.com/code.aspx?ID=31892
ça fait aussi les anagrammes entre autre.

Pourquoi ton dico est au format 1 mot par ligne ? c'est très lent d'accès en lecture et ça grossit la taille du dico inutilement.

Commentaire de yvemoreau le 08/09/2005 00:51:29

oups ç'est pas les anagrammes qu'on trouve ou bien tous les mots possibles avec un anagramme ??? enfin je sais plus...

c'est juste malheureux que ce soit pas en delphi BruNews moi et le vb ...pas sûr ...comment comparer des pommes avec des oranges ?  question temps ça m'a l'air bien aussi quoique c'est pas pareil du tout ...

Commentaire de BruNews le 08/09/2005 08:31:48 administrateur CS

Pas du VB mais C et ASM.
Ce n'est pas le langage mais du format de fichier dont je te parlais, 1 mot par ligne oblige à une recherche de fin de ligne pour extraire le mot suivant. Essaie avec une table en début de fichier indiquant combien de chaque longueur et ainsi tu peux coller tous les mots et les extraire juste au moment de la recherche, plus besoin de tout mettre en mémoire et c'est hyper rapide.

Commentaire de peanut_man le 02/12/2005 04:08:59

Bonjour a tous, je vais vous avouez que depuis le debut, tout ce que vous parlez me semble du chinois =S... je ne mis connais pas beaucoup en informatique mais je voudrais savoir comment utiliser ce programme qui me serais bien utile pour les anagrammes.Le problème est que : je le télécharge et ensuite quand il vien le temp de l'ouvrir après l'avoir ''d'ézipé'' mon ordinateur me dit que je ne peut l'ouvrir et qu'il me faut un autre programme.... je ne comprend pas comment faire... svp aidez moi à être capable de l'utiliser .

Commentaire de cavalier2400 le 06/08/2008 09:33:17

Bsr, Trois année plus tard, je ne trouve pas le dictionnaire, particulièrement pour tester la vitesse d'exécution (quand l'arbre grandit), par ce que j'ai réalisé presque le même travail mais en utilisant des bases de données!

Commentaire de yugos le 09/01/2010 22:27:37

Y a quand même beaucoup plus simple pour retrouver les anagrammes d'un mot.
Il suffit de trier les lettres d'un mot dans l'ordre lexicographique.
Exemple :
amer   ->  aemr
rame   ->  aemr
mare   ->  aemr
maree  ->  aeemr

Les anagrammes auront donc la même empreinte (le même hash).
On range çà dans une table de hachage (une std::map par exemple)
On a accès en temps constant à la liste des anagrammes d'un mot en calculant son hash
C'est ultra compacte. Le programme tient en une dizaine de ligne.
LireDico(const File *iDico,std::map<string,string>& oTable )
   string hash,mot;  
   while(!NotEnded(iDico) )
        LectureLigne(iDico,mot)
        CalculerEmpreinte(mot,hash)
        oTable.insert(hash,mot);

CalculerEmpeinte(const string& iMot, string& oHash)-> string
        ...

RetrouverAnagrammes(const string& iMot,
       const std::map<...>& iTable,
       std::list<string>& oAnagrammes)
  string hash;

CalculerEmpreinte(iMot,hash);
    std::map<...>::iterator it=iTable.find(hash);
    while ( it!= iTable.end() )
      oAnagrammes.push_back(it->second);

Voilà franchement 5 minutes à coder et beaucoup plus rapide (a optimiser si on veut en compressant les mots)

Commentaire de BruNews le 09/01/2010 23:05:08 administrateur CS

"1 dizaine de lignes" QU'ON VOIT dans le listing, mais combien de Ko STL qui bossent dans l'exe...
Grande plaisanterie que tout cela.

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Dictionnaire mot spécial [ par Xtazy ] Voila en fait c'est pa vraiment une question c'est pour savoir si quelq'un a deja fais un programme ( je n'en ai pa trouvé en le cherchant ) capable d Chercher un mot dans une string et prendre le(s) suivant(s) ... [ par bobalex19 ] Alors voila,Deja bonjour ;)Cela fait quelques jours que jesaye de trouver une solution a ce probleme mais je ny arrive pas ...Alors voila ce que jaime Cacher un mot de passe... [ par TiDaN326 ] Bonjour à tous...J'ai un léger problème de sécurité... J'ai un programme qui accède à une base de donnée... Évidemment, le mot de passe d'accès à cett Trouver la page d'un mot recherché ds un doc word [ par Delphal ] bonjour ts,j'ai trouvé une dificulté dans la lecture des interfaces d'utilisation de Word via Delphi, exactement ce qui concerne la recheche d'occuran ouvrir un fichier word contenant un mot de passe [ par jphrob ] bonjour,je souhaite ouvrir un fichier word mais celui possède un mot e passe. Mon objectif est de pouvoir remplir la fenetre password de word avec n'i DICTIONNAIRE DE MOTS [ par synthe_2000 ] Je cherche des fichiers au format texte ou ascii qui contiennent des listes de mots en français.Ou alors des dictionnaire français -anglais ou françai clic sur un mot, une phrase en delphi [ par papillotte ] Papillotte j'aimerais savoir s'il est possible de recuperer (selectionner) le mot lors d'un clic sur ce mot , et lo Memo, richedit [ par JermieSG1 ] Est-il possible d'insérer un mot en une position donnée.ex ligne 2 colonne 3je sais qu'avec Caretpos on peut obtenir les coordonnées du curseur mais e prendre une donne de type char dans un champs de texte [ par jfdeterme ] Salut a tous,j'ai une petit probleme voila un code source :unit principal;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Con Creation d'un dico et traducteur Sindarin.... [ par sireerik ] sireerikje cherche des info de programmation pour fair mon projet.comment sauvgarder un texte qui est dans un textbox dans un fichier txt ainsi que sa


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mars 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
293031    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,499 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales