Enrere Mòdul 6
Fonaments de programació. Llenguatge C/C++---
Pràctica    Resum teòric Exercicis
Pràctica d'ampliació

 
Sopa de lletres

En aquesta pràctica aprendrem  a fer una cerca d'una paraula en una matriu bidimensional de caràcters.

 

Desenvolupament de la pràctica

Imaginem que tenim una matriu bidimensional quadrada de caràcters de n files i n columnes, i volem trobar en aquesta matriu una paraula amagada que es pot llegir en una de les quatre direccions següents: 

  • horitzontal d'esquerra a dreta.
  • horitzontal de dreta a esquerra.
  • vertical de dalt a baix.
  • vertical de baix a dalt.

Per exemple, en la següent matriu 7x7 podem trobar les paraules sopa i lletres. La primera paraula es troba en la darrera columna vertical llegint de baix a dalt i la segona paraula es troba en la darrera fila horitzontal llegint d'esquerra a dreta.

Per simplificar no considerarem les direccions de les diagonals, encara que aquesta consideració podria formar part d'un dels projectes del curs.

B A C P G G J
J D C B L K M
S D D V Z R E
H H D D I I A
D T P K O U P
J D S A U U O
L L E T R E S
 

La cerca d'una paraula concreta s'ha d'efectuar en 4n cadenes diferents. Aquestes cadenes són:

  • n línies horitzontals d'esquerra a dreta.
  • n línies horitzontals de dreta a esquerra.
  • n línies verticals de dalt a baix.
  • n línies verticals de baix a dalt.

En aquest punt indicarem que si es consideren les direccions de les diagonals, hi ha 8n-4 cadenes més.

El programa que es presenta a continuació permet entrar tota la taula de caràcters i després una paraula. El programa buscarà la paraula entrada en les quatre direccions, en cas que es trobi indicarà en quina de les direccions s'ha trobat, a més d'indicar el número de fila o columna on es trobi. També imprimirà tota la taula, destacant en majúscula els caràcters de la paraula trobada.

Definiu un projecte nou anomenat m6pa1 i afegiu-li un arxiu de font C/C++ anomenat m6pa1.cpp. Escriviu el següent codi:

I //m6pa1.cpp: Sopa de lletres


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>


void introduccio_dades(void);
void hor_dre(char *);
void hor_esq(char *);
void ver_bai(char paraula[]);
void ver_dal(char paraula[]);
void mostrar_tauler();
void inicialitzar_tauler();

char tauler[11][11];
unsigned dimensio;

II void main (){
    char paraula[11];

    introduccio_dades();
    do{
        printf("Introduïu la paraula a buscar\n");
        printf("(premeu 0+INTRO per acabar)...");
        scanf(" %s",paraula);
        printf("\n\n");
        system("cls");

        hor_dre(paraula);
        hor_esq(paraula);
        ver_bai(paraula);
        ver_dal(paraula);

        mostrar_tauler();
        inicialitzar_tauler();
    }while(*paraula!='0');
}


III void hor_dre(char paraula[]){
    unsigned i,j;
    char text[10];
    char *punter;

    for(i=0;i<dimensio;i++){
        for(j=0;j<dimensio;j++) text[j]=tauler[i][j];

        if(!(punter=strstr(text, paraula))) continue;

        for (j=0;j<strlen(paraula);j++)
             punter[j]=toupper(punter[j]);

        for(j=0;j<dimensio;j++) tauler[i][j]=text[j];

        printf("\nEs troba a la fila horitzontal 
                 dreta %d\n",i);
        return;

    }
}

IV void hor_esq(char paraula[]){
    unsigned i,j;
    char text[10];
    char *punter;

    for(i=0;i<dimensio;i++){
        for(j=0;j<dimensio;j++)
             text[dimensio-j-1]=tauler[i][j];

        if(!(punter=strstr(text, paraula))) continue;

        for (j=0;j<strlen(paraula);j++)
              punter[j]=toupper(punter[j]);

        for(j=0;j<dimensio;j++)
                           tauler[i][j]=text[dimensio-j-1];
        printf("\nEs troba a la fila horitzontal
                 esquerra %d\n",i);
        return;

    }
}

V void ver_bai(char paraula[]){
    unsigned i,j;
    char text[10];
    char *punter;

    for(i=0;i<dimensio;i++){
        for(j=0;j<dimensio;j++) 
             text[j]=tauler[j][i];

        if(!(punter=strstr(text, paraula))) continue;

        for (j=0;j<strlen(paraula);j++)
              punter[j]=toupper(punter[j]);

        for(j=0;j<dimensio;j++)
              tauler[j][i]=text[j];

        printf("\nEs troba a la fila vertical
                cap a baix %d\n",i);
        return;

     }
}

VI void ver_dal(char paraula[]){
    unsigned i,j;
    char text[10];
    char *punter;

    for(i=0;i<dimensio;i++){
        for(j=0;j<dimensio;j++)
             text[j]=tauler[dimensio-j-1][i];

        if(!(punter=strstr(text, paraula))) continue;

        for (j=0;j<strlen(paraula);j++)
              punter[j]=toupper(punter[j]);

        for(j=0;j<dimensio;j++)
              tauler[dimensio-j-1][i]=text[j];

        printf("\nEs troba a la fila vertical
                cap a dalt %d\n",i);
        return;

    }
}

VII void introduccio_dades(void){
    unsigned i;
  

    printf("Introduïu la dimensió de la sopa de
            lletres\n");
    scanf(" %d",&dimensio);
    printf("Introduïu el tauler per files\n");
    for (i=0;i<dimensio;i++) scanf(" %s",tauler[i]);

}

VIII void inicialitzar_tauler(){
    unsigned i,j;


    for(i=0;i<dimensio;i++){
        for(j=0;j<dimensio;j++){
            tauler[i][j]=tolower(tauler[i][j]);
        }
    }

}


IX void mostrar_tauler(){
    unsigned i,j;


    for(i=0;i<dimensio;i++){
        for(j=0;j<dimensio;j++){
             printf("%c",tauler[i][j]);
        }
        printf("\n");

    }
}

Explicació del programa

Per tal de facilitar l'explicació del codi, aquest s'ha separat en 9 parts, la primera consisteix en les declaracions globals i arxius inclosos, la segona és la funció principal, i les 7 restants les diferents funcions emprades.

La matriu de caràcters que formarà la sopa de lletres es declara com una matriu global per tal de poder modificar-la des de totes les funcions. També es declara com a global la variable dimensio, que emmagatzema el nombre de files o columnes d'aquesta matriu.

Les set funcions d'aquest programa són:

  • introduccio_dades(). Aquesta funció permet obtenir del teclat la dimensió i els caràcters de la sopa de lletres

  • hor_dre(), hor_esq(),ver_bai(),ver_dal(). Aquestes quatre funcions comproven si la paraula buscada es troba a cadascuna de les n files o columnes corresponents, en cas afirmatiu indica el número de fila i columna i la direcció on s'ha trobat. També canvia els caràcters de la paraula trobats a majúscules amb la funció toupper(). D'aquesta forma, quan es mostri el tauler per pantalla, es veurà destacada la paraula buscada.

  • mostrar_tauler(). Mostra per pantalla el tauler. En el cas que s'hagi trobat la paraula buscada, els caràcters d'aquesta, dintre del tauler, es veuran en majúscules.

  • inicialitzar_tauler(). Per tal de no poder cercar una altra paraula a la mateixa sopa de lletres, aquesta funció únicament canvia a minúscules totes les lletres. Això es fa amb la funció tolower() que és la inversa de toupper().