Blame view

tree.c 7.29 KB
9cf06b18   mertz   debut_add_tree
1
  #include "tree.h"
f7d9ccda   mertz   ajout_libtree
2
  
df266b37   Thorsieger   ajout de commenta...
3
4
  //Contruction d'un arbre
  void cons_tree(struct node **ptr_tree, wchar_t val)
f7d9ccda   mertz   ajout_libtree
5
  {
9cf06b18   mertz   debut_add_tree
6
7
8
    *ptr_tree = malloc(sizeof(struct node));
    (*ptr_tree)->val = val;
    (*ptr_tree)->fin = 0;
df266b37   Thorsieger   ajout de commenta...
9
10
11
    (*ptr_tree)->nbr_fils = 0;
    (*ptr_tree)->fils = malloc(sizeof(struct node *)); //Tableau de taille 1 de pointeur de noeud
    (*ptr_tree)->fils[0] = NULL;                       //Cette node n'a pas de fils
f7d9ccda   mertz   ajout_libtree
12
13
  }
  
df266b37   Thorsieger   ajout de commenta...
14
  //Initialiation de chaque element du dictionnaire à nul
0f6db57b   Thorsieger   gestion des accen...
15
  void mk_empty_tree(dico *Dico)
9cf06b18   mertz   debut_add_tree
16
  {
df266b37   Thorsieger   ajout de commenta...
17
    for (int i = 0; i < Dico->taille; i++)
0f6db57b   Thorsieger   gestion des accen...
18
    {
df266b37   Thorsieger   ajout de commenta...
19
      Dico->tab_ptr_tree[i] = NULL; //Chaque element du dico est vide
0f6db57b   Thorsieger   gestion des accen...
20
    }
9cf06b18   mertz   debut_add_tree
21
  }
f7d9ccda   mertz   ajout_libtree
22
  
df266b37   Thorsieger   ajout de commenta...
23
  //Création d'un dictionnaire pour enregister les 26 lettres de l'alphabet
0f6db57b   Thorsieger   gestion des accen...
24
  void init_dico(dico *Dico)
9cf06b18   mertz   debut_add_tree
25
  {
0f6db57b   Thorsieger   gestion des accen...
26
    Dico->taille = 26;
df266b37   Thorsieger   ajout de commenta...
27
    Dico->tab_ptr_tree = malloc(Dico->taille * sizeof(struct node *));
0f6db57b   Thorsieger   gestion des accen...
28
    mk_empty_tree(Dico);
9cf06b18   mertz   debut_add_tree
29
  }
f7d9ccda   mertz   ajout_libtree
30
  
df266b37   Thorsieger   ajout de commenta...
31
32
  //ajout d'un mot dans le dictionnaire dans son arbre (liée à la première lettre du mot)
  void add(struct node **tab_ptr_tree, wchar_t val[], int taille, int fl)
03168857   mertz   create tree op
33
  {
df266b37   Thorsieger   ajout de commenta...
34
35
36
37
38
39
40
41
42
43
44
    if (tab_ptr_tree[fl] == NULL)cons_tree(&(tab_ptr_tree[fl]), val[0] + 97); //si l'arbre n'existe pas on le crée
  
    Node *noeudtest = tab_ptr_tree[fl];
    for (int i = 1; i < taille; i++)//on va travailler sur toutes les lettres du mot
    {
      int trouve = -1;
      for (int j = 0; j < noeudtest->nbr_fils; j++)//On recherche si la lettre existe déja
      {
        if (noeudtest->fils[j]->val == val[i])trouve = j;
      }
      if (trouve == -1)
03168857   mertz   create tree op
45
      {
df266b37   Thorsieger   ajout de commenta...
46
47
48
49
50
        //ajouter lettre
        noeudtest->nbr_fils++;
        noeudtest->fils = realloc(noeudtest->fils, (noeudtest->nbr_fils) * sizeof(struct node *));//On ajoute de la place dans le tableau de fils pour y mettre celui ci
        cons_tree(&(noeudtest->fils[(noeudtest->nbr_fils) - 1]), val[i]);
        trouve = noeudtest->nbr_fils - 1;
03168857   mertz   create tree op
51
      }
03168857   mertz   create tree op
52
  
df266b37   Thorsieger   ajout de commenta...
53
54
55
      noeudtest = noeudtest->fils[trouve]; //on jump au noeud suivant (lettre existante ou venant dtre créé)
    }
    noeudtest->fin = 1;//On a terminé le mot, cette lettre est la dernière du mot
9cf06b18   mertz   debut_add_tree
56
  }
f7d9ccda   mertz   ajout_libtree
57
  
df266b37   Thorsieger   ajout de commenta...
58
  //Calcul de la taille de la chaine de caractère donnée en paramètre
284154ca   Thorsieger   gestion des accents
59
  int size(wchar_t val[])
541fd894   mertz   on_avance_tree
60
61
  {
    int cpt = 0;
df266b37   Thorsieger   ajout de commenta...
62
63
64
65
    while (val != NULL && val[cpt] != '\0')
    {
      cpt++;
    }
541fd894   mertz   on_avance_tree
66
67
68
    return cpt;
  }
  
df266b37   Thorsieger   ajout de commenta...
69
  //Tous les caractères en majuscules sont mis en minuscule (même ceux avec accent)
89b9e3f8   Thorsieger   découpage d'un texte
70
  void toLowerCase(wchar_t mot[])
aeb78bdf   mertz   correction fin de...
71
  {
df266b37   Thorsieger   ajout de commenta...
72
73
74
75
76
77
    for (int i = 0; i < size(mot); i++)
    {
      if ((mot[i] <= 'Z' && mot[i] >= 'A') || (mot[i] >= 192 && mot[i] <= 214) || (mot[i] >= 216 && mot[i] <= 222))mot[i] += 32;
      else if (mot[i] == 138 || mot[i] == 140 || mot[i] == 142)mot[i] += 16;
      else if (mot[i] == 159)mot[i] += 96;
    }
aeb78bdf   mertz   correction fin de...
78
79
  }
  
df266b37   Thorsieger   ajout de commenta...
80
81
  //Récupération de la première lettre du mot et découpade de celui ci en fonction des séparateurs
  void splitcarac(dico *Dico, wchar_t message[], wchar_t separateur[])
89b9e3f8   Thorsieger   découpage d'un texte
82
  {
df266b37   Thorsieger   ajout de commenta...
83
  
c2f3660b   Thorsieger   correction bug ch...
84
85
86
87
    wchar_t *buffer;
    wchar_t *token = wcstok(message, separateur, &buffer);//On découpe le mot selon les séparateurs
    if(token == NULL)return;
  
df266b37   Thorsieger   ajout de commenta...
88
89
    //On récupére l'id de la première lettre dans notre dico
    int first_letter = -1;
c2f3660b   Thorsieger   correction bug ch...
90
    if (token[0] >= 'a' && token[0] <= 'z')
0f6db57b   Thorsieger   gestion des accen...
91
    {
c2f3660b   Thorsieger   correction bug ch...
92
      first_letter = (int)token[0] - 97;
0f6db57b   Thorsieger   gestion des accen...
93
94
95
    }
    else
    {
df266b37   Thorsieger   ajout de commenta...
96
      for (int i = 26; i < Dico->taille; i++)//On recherche si elle existe et qu'elle n'est pas de 'a' à 'z'
0f6db57b   Thorsieger   gestion des accen...
97
      {
c2f3660b   Thorsieger   correction bug ch...
98
        if (Dico->tab_ptr_tree[i]->val == token[0])
df266b37   Thorsieger   ajout de commenta...
99
100
101
102
        {
          first_letter = i;
          break;
        }
0f6db57b   Thorsieger   gestion des accen...
103
      }
df266b37   Thorsieger   ajout de commenta...
104
      if (first_letter == -1)//Elle n'exite pas, on l'ajoute
0f6db57b   Thorsieger   gestion des accen...
105
106
107
      {
        first_letter = Dico->taille;
        Dico->taille++;
df266b37   Thorsieger   ajout de commenta...
108
        Dico->tab_ptr_tree = realloc(Dico->tab_ptr_tree, (Dico->taille) * sizeof(struct node *));//On laisse la place pour ajouter une première lettre de mot
0f6db57b   Thorsieger   gestion des accen...
109
        Dico->tab_ptr_tree[first_letter] = NULL;
c2f3660b   Thorsieger   correction bug ch...
110
        cons_tree(&(Dico->tab_ptr_tree[first_letter]), token[0]);
0f6db57b   Thorsieger   gestion des accen...
111
112
      }
    }
df266b37   Thorsieger   ajout de commenta...
113
  
df266b37   Thorsieger   ajout de commenta...
114
115
    add(Dico->tab_ptr_tree, token, size(token), first_letter);//On ajoute le mot (jusqu'au séparateur) au dictionnaire
    if (buffer != NULL)splitcarac(Dico, buffer, separateur);//S'il reste des mots à ajouter on recommence
89b9e3f8   Thorsieger   découpage d'un texte
116
  }
541fd894   mertz   on_avance_tree
117
  
df266b37   Thorsieger   ajout de commenta...
118
  //Chargement du dictionnaire
f5b960c9   Thorsieger   utilisateur peut ...
119
  void load_dico(FILE *fp, dico *Dico, wchar_t separateur[])
9cf06b18   mertz   debut_add_tree
120
  {
df266b37   Thorsieger   ajout de commenta...
121
122
123
124
125
126
127
    wchar_t val[3000];//Nombre de caractère max sur une page
  
    while (fwscanf(fp, L"%ls", val) == 1)
    {
      toLowerCase(val);//Les caractères sont mis en miniscule
      splitcarac(Dico, val, separateur);//On ajoute tous les mots au dictionnaire
    }
541fd894   mertz   on_avance_tree
128
  
df266b37   Thorsieger   ajout de commenta...
129
130
    //On peut tester la bonne ou mauvaise terminaison de la lecture
    if (ferror(fp))wprintf(L"ERREUR de lecture\n");
9cf06b18   mertz   debut_add_tree
131
  }
f7d9ccda   mertz   ajout_libtree
132
  
df266b37   Thorsieger   ajout de commenta...
133
  //On libère toute la mémoire de chaque arbre
7ab3be6b   Thorsieger   debut free
134
  void free_tree(struct node *ptr_tree)
9cf06b18   mertz   debut_add_tree
135
  {
df266b37   Thorsieger   ajout de commenta...
136
137
138
139
140
141
142
    if (ptr_tree == NULL)return;//On a terminé
    if (ptr_tree->nbr_fils == 0)//Le noeud n'a pas de fils on peut libérer la mémoire
    {
      free(ptr_tree->fils);
      return;
    }
    for (int i = (ptr_tree->nbr_fils) - 1; i >= 0; i--)//si le noeud à des fils ré-exécute la fontion
7ab3be6b   Thorsieger   debut free
143
    {
131759ee   Thorsieger   fin free arbre
144
      free_tree(ptr_tree->fils[i]);
7ab3be6b   Thorsieger   debut free
145
146
      free(ptr_tree->fils[i]);
    }
131759ee   Thorsieger   fin free arbre
147
    free(ptr_tree->fils);
7ab3be6b   Thorsieger   debut free
148
149
  }
  
df266b37   Thorsieger   ajout de commenta...
150
  //On libére la mémoire du dictionnaire
0f6db57b   Thorsieger   gestion des accen...
151
  void free_dico(dico Dico)
7ab3be6b   Thorsieger   debut free
152
  {
df266b37   Thorsieger   ajout de commenta...
153
    for (int i = 0; i < Dico.taille; i++)//On libére chaque arbre
7ab3be6b   Thorsieger   debut free
154
    {
df266b37   Thorsieger   ajout de commenta...
155
      if (Dico.tab_ptr_tree[i] != NULL)
7ab3be6b   Thorsieger   debut free
156
      {
0f6db57b   Thorsieger   gestion des accen...
157
158
        free_tree(Dico.tab_ptr_tree[i]);
        free(Dico.tab_ptr_tree[i]);
7ab3be6b   Thorsieger   debut free
159
160
      }
    }
0f6db57b   Thorsieger   gestion des accen...
161
    free(Dico.tab_ptr_tree);
9cf06b18   mertz   debut_add_tree
162
  }
76053da1   Thorsieger   update des fichiers
163
  
df266b37   Thorsieger   ajout de commenta...
164
165
  //Recherche dans le dictionnaire d'un mot
  int find_mot(dico Dico, wchar_t mot[])
76053da1   Thorsieger   update des fichiers
166
  {
df266b37   Thorsieger   ajout de commenta...
167
    if (mot == NULL)return 0;
16e67e7e   Thorsieger   l'utilisateur peu...
168
  
df266b37   Thorsieger   ajout de commenta...
169
170
171
172
173
174
175
176
    int fl = -1;
    if (mot[0] >= 'a' && mot[0] <= 'z')
    {
      fl = (int)mot[0] - 97;
    }
    else
    {
      for (int i = 26; i < Dico.taille; i++)
76053da1   Thorsieger   update des fichiers
177
      {
df266b37   Thorsieger   ajout de commenta...
178
        if (Dico.tab_ptr_tree[i]->val == mot[0])
0f6db57b   Thorsieger   gestion des accen...
179
        {
df266b37   Thorsieger   ajout de commenta...
180
181
          fl = i;
          break;
0f6db57b   Thorsieger   gestion des accen...
182
        }
0f6db57b   Thorsieger   gestion des accen...
183
      }
3980f042   Thorsieger   affichage des mot...
184
185
186
187
188
      if (fl == -1){
        wprintf(mot);
        wprintf(L"\n");
        return 1;
      }
df266b37   Thorsieger   ajout de commenta...
189
    }
0f6db57b   Thorsieger   gestion des accen...
190
  
df266b37   Thorsieger   ajout de commenta...
191
192
193
    int taille = size(mot);
    if (taille == 1 && Dico.tab_ptr_tree[fl] != NULL)
    {
3980f042   Thorsieger   affichage des mot...
194
195
196
197
198
      if (Dico.tab_ptr_tree[fl]->fin == 0){
        wprintf(mot);
        wprintf(L"\n");
        return 1;
        }else return 0; //vrais
df266b37   Thorsieger   ajout de commenta...
199
    }
c2f3660b   Thorsieger   correction bug ch...
200
    if (Dico.tab_ptr_tree[fl] == NULL)return 1; //faux
76053da1   Thorsieger   update des fichiers
201
  
df266b37   Thorsieger   ajout de commenta...
202
203
204
    struct node *ptr_node = Dico.tab_ptr_tree[fl];
    for (int i = 1; i < taille; i++)
    {
3980f042   Thorsieger   affichage des mot...
205
206
207
208
209
      if (ptr_node->nbr_fils == 0){
        wprintf(mot);
        wprintf(L"\n");
        return 1;
      }
df266b37   Thorsieger   ajout de commenta...
210
      for (int k = 0; k < (ptr_node->nbr_fils); k++)
76053da1   Thorsieger   update des fichiers
211
      {
df266b37   Thorsieger   ajout de commenta...
212
213
214
215
216
        if (ptr_node->fils[k]->val == mot[i])
        {
          ptr_node = ptr_node->fils[k];
          break;
        }
3980f042   Thorsieger   affichage des mot...
217
218
219
        else if (k + 1 == ptr_node->nbr_fils){
          wprintf(mot);
          wprintf(L"\n");
df266b37   Thorsieger   ajout de commenta...
220
          return 1;
3980f042   Thorsieger   affichage des mot...
221
        }
76053da1   Thorsieger   update des fichiers
222
      }
df266b37   Thorsieger   ajout de commenta...
223
    }
76053da1   Thorsieger   update des fichiers
224
  
3980f042   Thorsieger   affichage des mot...
225
226
227
228
229
    if (ptr_node->fin == 0){
      wprintf(mot);
      wprintf(L"\n");
      return 1;
    }else return 0;
76053da1   Thorsieger   update des fichiers
230
231
  }
  
df266b37   Thorsieger   ajout de commenta...
232
233
  //Test de présence de chaque mot du fichier de l'utilisateur
  int find_erreur(dico Dico, FILE *fp, wchar_t separateur[])
76053da1   Thorsieger   update des fichiers
234
  {
16e67e7e   Thorsieger   l'utilisateur peu...
235
    wchar_t val[3000];
df266b37   Thorsieger   ajout de commenta...
236
    int cpt_erreur = 0;
0f6db57b   Thorsieger   gestion des accen...
237
  
3980f042   Thorsieger   affichage des mot...
238
239
    wprintf(L"Mots non reconnus :\n");
  
df266b37   Thorsieger   ajout de commenta...
240
241
242
243
244
    while (fwscanf(fp, L"%ls", val) == 1)
    {
      toLowerCase(val);//Fichier mit en minuscule
      cpt_erreur += split_text(Dico, val, separateur);//découpage et analyse du texte selon les séparateur
    }
0f6db57b   Thorsieger   gestion des accen...
245
  
df266b37   Thorsieger   ajout de commenta...
246
247
248
249
    //On peut tester la bonne ou mauvaise terminaison de la lecture
    if (ferror(fp))wprintf(L"ERREUR de lecture\n");
  
    return cpt_erreur;
76053da1   Thorsieger   update des fichiers
250
  }
0f6db57b   Thorsieger   gestion des accen...
251
  
df266b37   Thorsieger   ajout de commenta...
252
253
254
255
  //Découpage et analyse du texte selon les séparateur
  int split_text(dico Dico, wchar_t message[], wchar_t separateur[])
  {
    if (message[0] == 0)return 0;
0f6db57b   Thorsieger   gestion des accen...
256
    wchar_t *buffer;
df266b37   Thorsieger   ajout de commenta...
257
258
259
    wchar_t *token = wcstok(message, separateur, &buffer);//Découpage selon les caractère de séparation
    int err = find_mot(Dico, token);//recherche de la présence du mot dans le dictionnaire
    if (buffer != NULL)err += split_text(Dico, buffer, separateur);
0f6db57b   Thorsieger   gestion des accen...
260
261
  
    return err;
4a5c0af6   mertz   correction erreur...
262
  }