Téléchargé 1 fois
Vote des utilisateurs
0
0
Détails
Référencé dans
Navigation
Solveur mots mêlés
Solveur mots mêlés
A partir d'un fichier "tableau.txt" contenant une grille rectangulaire de lettres et d'un fichier "mots.txt" contenant une liste de mots, le solveur trouve tous les mots dans la grille (dans les 8 directions possibles), les barre virtuellement et fournit à l'entrée standard les lettres restantes.
Le code ne comporte pas de variables externes, ce qui permet une adaptation relativement simple vers de la POO.
Les tableaux ne sont (presque pas) employés, dans un but d'efficience mémoire. Pour cette même raison, puisque les dimensions de tableaux ne peuvent être définies pendant l'exécution, le travail ne se fait pas sur des indices bidimensionnels, mais sur des pointeurs vers des données unidimensionelles.
Le code ne comporte pas de variables externes, ce qui permet une adaptation relativement simple vers de la POO.
Les tableaux ne sont (presque pas) employés, dans un but d'efficience mémoire. Pour cette même raison, puisque les dimensions de tableaux ne peuvent être définies pendant l'exécution, le travail ne se fait pas sur des indices bidimensionnels, mais sur des pointeurs vers des données unidimensionelles.
Le problème à résoudre reste bien sûr identique.
La démarche pour le résoudre est différente (merci à yahiko,medinoc et diogene):
La démarche pour le résoudre est différente (merci à yahiko,medinoc et diogene):
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Charger les c lettres de la grille Pour toutes les c lettres de la grille (c=0...tailleGrille-1) Pour les i directions (i=0...7) Enregistrer la SousGrille sg[c,i] : séquence de caractères partant de c et rejoignant le bord de la grille dans la direction i Pour tous les mots M à trouver dans la grille (M=0....nMots) Pour toutes les c lettres de la grille (c=0...tailleGrille-1) Pour les i directions (i=0...7) si strncmp(mot[M],SousGrille[c,i],strlen(mot))==0 alors on met dans la grille les lettres composant la SousGrille à ' ' Pour toutes les c lettres de la grille (c=0...tailleGrille-1) Si c<>' ', imprimer c |
Code : | Sélectionner tout |
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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | #include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> #define MAX_MOT 50 #define DIM_MAX 60 #define MAXGRILLE 1500 /*TYPES*/ const short incr1[8]= {-1,0,1, 0,-1,1, 1,-1}; const short incr2[8]= { 0,1,0,-1, 1,1,-1,-1}; enum DIRECTION {NORD=0,EST,SUD,OUEST,NORDEST,SUDEST,SUDOUEST,NORDOUEST}; typedef int indice_t; typedef struct { char *listeCars; enum DIRECTION sens; indice_t indice; } SousGrille_t; typedef struct { SousGrille_t *y; } SousGrilleParCar_t; typedef struct { char *grille; SousGrilleParCar_t *x; int largeur; int hauteur; } GrilleMotsMeles_t; /*PROTOTYPES*/ GrilleMotsMeles_t *initGrilleMotsMeles(FILE *); char *initCaracteres(FILE *,int *,int *); SousGrille_t *initElementSousGrille(char *,int,int,int,int); void resoudreGrille(GrilleMotsMeles_t *,FILE*); void afficherResultat(GrilleMotsMeles_t *); void assure(void *, const char *); /*SOLVEUR DE MOTS MELES PRE: "tableau.txt" contient la grille de caractères "mots.txt" contient un mot par ligne. Ce sont les mots dont les caractères doivent être barrés dans la grille POST "result.txt" contient la suite de lettre de la grille qui n'ont pas été barrées (sens gauche vers droite, haut vers bas) */ int main() { GrilleMotsMeles_t *grillemelimelo; FILE* fGrille; FILE* fMots; /*redirection de la sortie standard vers RESULT.TXT*/ freopen("RESULT.TXT","w",stdout); /*initialise la grille et les structures sous-jacentes*/ fGrille=fopen("tableau.txt","r"); grillemelimelo=initGrilleMotsMeles(fGrille); /*trouve les mots à chercher dans la grille et barre les lettres une fois trouvées*/ fMots=fopen("mots.txt","r"); resoudreGrille(grillemelimelo,fMots); /*affiche les lettres qui n'ont pas été barrées*/ afficherResultat(grillemelimelo); return 1; } /*initialisation de la structure GrilleMotMeles_t à partir d'un tableau de caractères présent dans le fichier fichierGrille*/ GrilleMotsMeles_t *initGrilleMotsMeles(FILE *fichierGrille) { GrilleMotsMeles_t *p; SousGrille_t *tmp; indice_t tailleGrille; int i,j; p=(GrilleMotsMeles_t *)malloc(sizeof(GrilleMotsMeles_t)); assure(p,"initGrilleMotsMeles: erreur malloc"); /*on a besoin d'avoir tous les caractères de la grille de mots mêlés*/ p->grille=initCaracteres(fichierGrille,&(p->hauteur),(&p->largeur)); tailleGrille=p->hauteur*p->largeur; p->x=calloc(tailleGrille,sizeof(SousGrilleParCar_t)); assure(p,"initGrilleMotsMeles: erreur calloc"); /*chargement des données*/ /*pour tous les caractères de la grille...*/ for(i=0;i<tailleGrille;i++) { p->x[i].y=calloc(8,sizeof(SousGrille_t)); assure(p->x[i].y,"initCaracteres:erreur calloc"); /*...pour les 8 directions DIR...*/ for(j=0;j<8;j++) { /*...on charge les sous-grilles partant du caractère et allant jusqu'au bord de la grille, dans la direction DIR*/ tmp=initElementSousGrille(p->grille,i,p->hauteur,p->largeur,j); memcpy((p->x[i].y)+j,tmp,sizeof(SousGrille_t)); free(tmp); }; }; return p; } /*charge la grille de caractères, base de la Grille de Mots Meles*/ char *initCaracteres(FILE *f,int *hauteur,int *largeur) { int j,k; char *p; char c; long taille; p=calloc(MAXGRILLE+1,sizeof(char)); assure(p,"initCaracteres:erreur calloc"); j=0; taille=0; *largeur=0; for (k=0;(c=getc(f))!=EOF; k++) if (c!='\n') { j++; taille++; /*on met la lettre en majuscules*/ p[k]=toupper(c); } else { *largeur=j; j=0; k--; /*on ne met pas '\n' dans le tableau*/ }; *hauteur=taille/(*largeur); return p; } /*pour un caractère de la grille et une direction donnée, renvoie un pointeur sur une chaine égale à la sous-grille partant du caractère donné, dans la direction donnée, et se terminant en bord de grille*/ SousGrille_t *initElementSousGrille(char *grille,int i, int h, int l, int numDir) { char tmpCar[DIM_MAX]; int k,increment; SousGrille_t *p; p=malloc(sizeof(SousGrille_t)); assure(p,"initElementSousGrille: erreur malloc"); p->indice=i; p->sens=numDir; /*détermination de l'incrément des indices à partir de la direction*/ increment=incr1[numDir]*l+incr2[numDir]; k=0; /* il y a au moins une lettre de la grille à charger*/ /* on les mémorise, et on charge la suivante, jusqu'à ce que celle-ci dépasse le bord de la grille*/ /*quand on se déplace vers la gauche de la grille, on n'enregistre pas l'élement pour lequel l'indice%largeur==largeur-1*/ /*quand on se déplace vers la droite de la grille, on n'enregistre pas l'élement pour lequel l'indice%largeur==0*/ do{ tmpCar[k++]=grille[i]; i+=increment; if(incr2[numDir]>0 && i%l==0) break; else if(incr2[numDir]<0 && i%l==l-1) break; } while (i>=0 && i<l*h); tmpCar[k]='\0'; p->listeCars=calloc(k+1,sizeof(char)); assure(p->listeCars,"initSousGrille:erreur calloc"); strcpy(p->listeCars,tmpCar); return p; } /*pour tous les mots M de fichierMots (un mot par ligne), on va trouver la sous-grille (couple caractère-directio), pour lequel le début de la sous-grille égale le mot M.*/ void resoudreGrille(GrilleMotsMeles_t *p,FILE* fichierMots) { char mot [MAX_MOT]; int i,k,dir,increment,len; indice_t tailleGrille; tailleGrille=p->largeur*p->hauteur; /*tant qu'il y a une ligne contenant un mot*/ while ((fscanf(fichierMots,"%s\n",mot))!=EOF) { len=strlen(mot); /*on met le mot en majuscules*/ for(i=0;i<len;i++) mot[i]=toupper(mot[i]); /*on va rechercher dans pour tous les les caractères de la grille....*/ for(i=0;i<tailleGrille;i++) /*...toutes les directions*/ for(dir=0;dir<8;dir++) { /*test d'égalité entre le mot et le début de la listeCars*/ if (0==strncmp(mot,p->x[i].y[dir].listeCars,len)) { /*la SousGrille_t [i,dir] égale le mot à trouver*/ /*on élimine de la grille les lettres du mot trouvé, en les mettant à ' '*/ increment=incr1[dir]*(p->largeur)+incr2[dir]; for(k=0;k<len;k++) p->grille[i+k*increment]= ' '; } } } return; } void afficherResultat(GrilleMotsMeles_t *p) { char c; /*on affiche toutes les lettres de la grilles qui n'ont pas été supprimées (= différentes de ' ')*/ while((c=*(p->grille++))!='\0') if (c!=' ') putchar(c); return; } /*affiche un message si pointeur ptr NULL*/ void assure(void *ptr, const char *msg) { if (ptr==NULL) { fprintf(stdout,"\n"); fprintf(stdout,msg); fprintf(stdout,"\n"); fflush(stdout); exit(EXIT_FAILURE); } } |
Suite aux conseils de Sve@r et diogene :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Charger S: ensemble toutes les c lettres de la grille Charger S', copie de S Pour tous les mots M à trouver dans la grille (M=0....nMots) Pour toutes les c lettres de S (c=0...tailleGrille-1) si c= M[1] Pour les i directions (i=0...7) Charger la SousGrille sg[c,i] : séquence de caractères partant de c et rejoignant le bord de la grille dans la direction i si strncmp(mot[M],SousGrille[c,i],strlen(mot))==0 mot trouve=vrai; mettre dans la grille les lettres composant la SousGrille à '\0' dans la grille S passer au mot suivant Pour toutes les c lettres de la grille G'(c=0...tailleGrille-1) Si c<>'\0 ', imprimer c |
Code : | Sélectionner tout |
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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | #include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include <time.h> #define MAX_MOT 50 #define DIM_MAX 60 #define MAXGRILLE 1500 /*TYPES*/ const short incr1[8]= {-1,0,1, 0,-1,1, 1,-1}; const short incr2[8]= { 0,1,0,-1, 1,1,-1,-1}; typedef int indice_t; typedef struct { char *grille; char *ignore; int largeur; int hauteur; } GrilleMotsMeles_t; /*PROTOTYPES*/ GrilleMotsMeles_t *initGrilleMotsMeles(FILE *); void initCaracteres(FILE *,GrilleMotsMeles_t *); char *initElementSousGrille(GrilleMotsMeles_t *,int,int); void resoudreGrille(GrilleMotsMeles_t *,FILE*); void afficherResultat(GrilleMotsMeles_t *); void assure(void *, const char *); /*SOLVEUR DE MOTS MELES PRE: "tableau.txt" contient la grille de caractères "mots.txt" contient un mot par ligne. Ce sont les mots dont les caractères doivent être barrés dans la grille POST "result.txt" contient la suite de lettre de la grille qui n'ont pas été barrées (sens gauche vers droite, haut vers bas) */ int main() { GrilleMotsMeles_t *grillemelimelo; FILE* fGrille; FILE* fMots; clock_t debut,fin; debut=clock(); /*redirection de la sortie standard vers RESULT.TXT*/ freopen("RESULT.TXT","w",stdout); /*initialise la grille et les structures sous-jacentes*/ fGrille=fopen("tableau.txt","r"); assure(fGrille,"Erreur ouverture fichier tableau.txt"); grillemelimelo=initGrilleMotsMeles(fGrille); /*trouve les mots à chercher dans la grille et barre les lettres une fois trouvées*/ fMots=fopen("mots.txt","r"); assure(fMots,"Erreur ouverture fichier mots.txt"); resoudreGrille(grillemelimelo,fMots); /*affiche les lettres qui n'ont pas été barrées*/ afficherResultat(grillemelimelo); fin=clock(); printf("\nTemps run : %2.30f secondes\n",(double) (fin-debut)/CLOCKS_PER_SEC); return 1; } /*initialisation de la structure GrilleMotMeles_t à partir d'un tableau de caractères présent dans le fichier fichierGrille*/ GrilleMotsMeles_t *initGrilleMotsMeles(FILE *fichierGrille) { GrilleMotsMeles_t *pGrille; indice_t tailleGrille; int i,j; pGrille=malloc(sizeof(GrilleMotsMeles_t)); assure(pGrille,"initGrilleMotsMeles: erreur malloc"); /*on a besoin d'avoir tous les caractères de la grille de mots mêlés*/ initCaracteres(fichierGrille,pGrille); pGrille->ignore=calloc(MAXGRILLE+1,sizeof(char)); assure(pGrille->ignore,"initCaracteres:erreur calloc"); strcpy(pGrille->ignore,pGrille->grille); return pGrille; } /*charge la grille de caractères, base de la Grille de Mots Meles*/ void initCaracteres(FILE *f,GrilleMotsMeles_t *pGrille) { int j,k; char c; long taille; pGrille->grille=calloc(MAXGRILLE+1,sizeof(char)); assure(pGrille->grille,"initCaracteres:erreur calloc"); j=0; taille=0; pGrille->largeur=0; for (k=0;(c=getc(f))!=EOF; k++) if (c!='\n') { j++; taille++; /*on met la lettre en majuscules*/ pGrille->grille[k]=toupper(c); } else { pGrille->largeur=j; j=0; k--; /*on ne met pas '\n' dans le tableau*/ }; pGrille->hauteur = taille/pGrille->largeur; return; } /*pour un caractère de la grille et une direction donnée, renvoie un pointeur sur une chaine égale à la sous-grille partant du caractère donné, dans la direction donnée, et se terminant en bord de grille*/ char *initElementSousGrille(GrilleMotsMeles_t *pGrille,int point, int numDir) { char tmpCar[DIM_MAX]; int i,k,increment; char *pReturnValue; /*détermination de l'incrément des indices à partir de la direction*/ increment=incr1[numDir]*pGrille->largeur+incr2[numDir]; k=0; i=point; /* il y a au moins une lettre de la grille à charger*/ /* on les mémorise, et on charge la suivante, jusqu'à ce que celle-ci dépasse le bord de la grille*/ /*quand on se déplace vers la gauche de la grille, on n'enregistre pas l'élement pour lequel l'indice%largeur==largeur-1*/ /*quand on se déplace vers la droite de la grille, on n'enregistre pas l'élement pour lequel l'indice%largeur==0*/ do{ tmpCar[k++]=pGrille->grille[i]; i+=increment; if(incr2[numDir]>0 && i%pGrille->largeur==0) break; else if(incr2[numDir]<0 && i%pGrille->largeur==pGrille->largeur-1) break; } while (i>=0 && i<pGrille->largeur*pGrille->hauteur); tmpCar[k]='\0'; pReturnValue=calloc(k+1,sizeof(char)); assure(pReturnValue,"initSousGrille:erreur calloc"); strcpy(pReturnValue,tmpCar); return; } /*pour tous les mots M de fichierMots (un mot par ligne), on va trouver la sous-grille (couple caractère-direction), pour lequel le début de la sous-grille égale le mot M.*/ void resoudreGrille(GrilleMotsMeles_t *pGrille,FILE* fichierMots) { char mot [MAX_MOT]; char *pTmp; int i,k,dir,increment,len; indice_t tailleGrille; int motTrouve; tailleGrille=(pGrille->largeur)*(pGrille->hauteur); /*tant qu'il y a une ligne contenant un mot*/ while ((fscanf(fichierMots,"%s\n",mot))!=EOF) { len=strlen(mot); /*on met le mot en majuscules*/ for(i=0;i<len;i++) mot[i]=toupper(mot[i]); motTrouve=0; /*on va rechercher dans pour tous les caractères de la grille....*/ for(i=0;i<tailleGrille;i++) { /* si le caractères de la grille et la première lettre du mot correspondent*/ if(mot[0]==pGrille->grille[i]) /*...toutes les directions*/ for(dir=0;dir<8;dir++){ pTmp=initElementSousGrille(pGrille,i,dir); /*test d'égalité entre le mot et le début de la listeCars*/ if (0==strncmp(mot,pTmp,len)) { /*la SousGrille_t [i,dir] égale le mot à trouver*/ motTrouve=1; /*on élimine de la grille les lettres du mot trouvé, en les mettant à ' '*/ increment=incr1[dir]*(pGrille->largeur)+incr2[dir]; for(k=0;k<len;k++) pGrille->ignore[i+k*increment]= '\0'; break; }; free(pTmp); } if (motTrouve) break; } } return; } void afficherResultat(GrilleMotsMeles_t *p) { int i; int taille = p->largeur*p->hauteur; /*on affiche toutes les lettres de la grilles dont ignore sont encore égales à 0*/ for(i=0; i<taille;i++) if(p->ignore[i]) putchar(p->grille[i]); } /*affiche un message si pointeur ptr NULL*/ void assure(void *ptr, const char *msg) { if (ptr==NULL) { fprintf(stdout,"\n"); fprintf(stdout,msg); fprintf(stdout,"\n"); fflush(stdout); exit(EXIT_FAILURE); } } |
Developpez.com décline toute responsabilité quant à l'utilisation des différents éléments téléchargés.