[C]Comment Afficher l'intégralité d'un dictionnaire sous forme d'arbre

Bonsoir la zone!

Je viens vous demander une petite aide et/ou une idée de comment effectuer la chose.

j’ai une structure Cellule de cette forme:

[codebox]typedef struct Cellule{ char Carac;
int FinMot;
struct Cellule * Suivant[26];
}Cellule;[/codebox]

Pour “initialiser” le dictionnaire, j’alloue une cellule à 0, et ensuite j’ajoute mes mots.

Une fois le dictionnaire complet, les champs Suivant[i] contiennent les adresses des cellules suivantes (s’il en existe)
La balise “FinMot” permet de dire si la cellule sur laquelle on se trouve correspond à une fin de mot.

J’ai essayé un peu tout et n’importe quoi (en récursif) pour afficher mon dictionnaire complet mais je n’y arrive pas.
Le premier mot s’affiche mais je n’ai que les terminaisons des autres.

Auriez vous une idée pour solutionner mon problème (ou au moins une piste…)

Merci d’avance

(Après en cas de désespoir, je m’essayerai au Ballmer’s Peak)

J’ai lu et relu ton message et je comprend pas des masses ce que tu veux faire.

Pseudo-code C

parcourirCellule(Cellule* cell) { int i; for(i = 0; i < 26; ++i) { if(cell->Suivant[i] != null) { afficher(cell-> Carac); /*Euh c'est un char c'est normal? */ parcourirCellule(cell->Suivant[i]); } } }

Logiquement je vois pas pourquoi ce code t’afficherais pas tout ton “dictionnaire” (ça le parcourt en profondeur par contre).
Pourrais-tu expliciter un peu plus ce que tu veux faire, ça aiderait sûrement.

Te faut just construire un buffer que tu passes dans ta recursivite par exemple et tu imprimmes que quand t’es sur un “mot” en imprimmant le buffer en cours. La taille du buffer doit etre ou variable (safe), ou au pire la taille du mot le plus long dans ton dictionnaire (facile).

[quote=« MadGnome, post:2, topic: 36861 »]J’ai lu et relu ton message et je comprend pas des masses ce que tu veux faire.

Pseudo-code C

parcourirCellule(Cellule* cell) { int i; for(i = 0; i < 26; ++i) { if(cell->Suivant[i] != null) { afficher(cell-> Carac); /*Euh c'est un char c'est normal? */ parcourirCellule(cell->Suivant[i]); } } }

Logiquement je vois pas pourquoi ce code t’afficherais pas tout ton « dictionnaire » (ça le parcourt en profondeur par contre).
Pourrais-tu expliciter un peu plus ce que tu veux faire, ça aiderait sûrement.[/quote]

Bah c’est presque ce que j’ai fait, en prenant en compte le flag de fin de mot pour afficher un « \n » et passer à la ligne

Bah on m’a vaguement parlé de ce genre de solution et je pense donc que ce doit être ce que je devrais faire. je vais y reflechir davantage!

merci. Si d’autres avis arrivent, je suis toujours preneur

Ce que tu veux faire n’est pas très clair. Pourquoi un seul caractère par cellule ? Pourquoi 26 elements dans Suivant ?

Peu etre que si tu donnes ton code qui ne marche pas, cela pourrait aider à comprendre ce que tu essaies de faire et corriger ce qui ne va pas.

fonction f (cellule c, string s) : void
si c.FinMot = vrai
alors
afficher s + "\n"
sinon
pour i de 1 à 26
faire
f(c.Suivant[i],c.Carac+s)
finpour
finsi
finfonction

init : f(c,"")

PS : + : concaténation de string

[quote=« BokLM, post:5, topic: 36861 »]Ce que tu veux faire n’est pas très clair. Pourquoi un seul caractère par cellule ? Pourquoi 26 elements dans Suivant ?

Peu etre que si tu donnes ton code qui ne marche pas, cela pourrait aider à comprendre ce que tu essaies de faire et corriger ce qui ne va pas.[/quote]
Il fait un arbre 26-aire, ou [A-Z]-aire si tu préfères :slight_smile:

Merci bien.

Grace à votre aide j’ai enfin pu m’en sortir.

Ca donne ça:

[codebox]//dans me fonction d'affichage
for(i=0;i<26;i++)
	if(Pointeur->enfants[i]!=NULL)
	{
		Parcours(Pointeur->enfants[i], Mot);
		memset(&Mot[strlen(Mot)-1],0,45-strlen(Mot)-1);
	}

void Parcours(node * Pointeur, char * str)
{
int i;
if(noeud_est_un_mot(Pointeur))
{
str[strlen(str)]=Pointeur->lettre;
printf("%s\n",str);
}
else
{
str[strlen(str)]=Pointeur->lettre;
for(i=0;i<26;i++)
if(Pointeur->enfants[i]!=NULL)
{
Parcours(Pointeur->enfants[i],str);
memset(&str[strlen(str)-1],0,45-strlen(str)-1);
}

}

}[/codebox]

Encore merci

[quote=“xevius, post:8, topic: 36861”]Merci bien.

Grace à votre aide j’ai enfin pu m’en sortir.

Ca donne ça:

[codebox]//dans me fonction d'affichage
for(i=0;i<26;i++)
	if(Pointeur->enfants[i]!=NULL)
	{
		Parcours(Pointeur->enfants[i], Mot);
		memset(&Mot[strlen(Mot)-1],0,45-strlen(Mot)-1);
	}

void Parcours(node * Pointeur, char * str)
{
int i;
if(noeud_est_un_mot(Pointeur))
{
str[strlen(str)]=Pointeur->lettre;
printf("%s\n",str);
}
else
{
str[strlen(str)]=Pointeur->lettre;
for(i=0;i<26;i++)
if(Pointeur->enfants[i]!=NULL)
{
Parcours(Pointeur->enfants[i],str);
memset(&str[strlen(str)-1],0,45-strlen(str)-1);
}

}

}[/codebox]

Encore merci[/quote]

Je ne pense pas que ton code soit correct. Déjà avec le str[strlen(str)]=Pointeur->lettre; tu écrase ton ‘\0’. Ca marche peut-être parce qu’au départ tu as des zéros dans la zone mémoire qui stocke Mot mais fait attention à ça.
Deuxième problème : il faut que tu continues ton parcours même quand le noeud sur lequel tu es est un mot. Comment fait tu pour afficher l’arbre contenant ‘geek’ et ‘geekzone’ sinon ?

Enfin, j’imagine que tu utilises memset(&Mot[strlen(Mot)-1],0,45-strlen(Mot)-1); pour effacer ce que vient de faire la fonction Parcours que tu viens d’appeler, mais pourquoi ne pas effacer juste le dernier caractère plutôt que toute la fin du buffer ?

Ca parait en effet bien sale comme code sans vouloir etre mheuuuuuchant :slight_smile:

ça n’efface pas le ‹ \0 ›, car, (et c’est ce que tu dis après) j’ai toujours des 0 à la suite

bah je continue, c’est juste que si c’est un mot j’affiche ‹ \n › puis je continue le parcours. (avec la récursivité)
Mais c’est vrai qu’en relisant je me pose des questions! je vais regarder!

Je fais ça pour éviter le problème cité en premier, le risque de suppression du ‹ \0 ›

Pour Glop, je t’accordes que ça ne doit pas être la solution la plus ‹ élégante › mais c’est pas trop moche non plus!
Si?