marcelogarberoglio / PI

Para realizar consultas
5 stars 0 forks source link

TP8Ej7 #223

Open lulostupnik opened 1 year ago

lulostupnik commented 1 year ago

Hola Marcelo, como estas? Queria saber si la solucion a la que llego en este ejercicio te parece adecuada, o si hay algo que mejorar, ya que me resulta medio "fea" la manera que manejo el vector de struct posiciones, mandandolo como parametro y retornandolo en todas las funciones.

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

#define FILS 6
#define COLS 7
#define CANT_DIRECCIONES 8
#define BLOQUE 10

typedef enum {DER=0, IZQ, ABA, ARR, I_AR, I_AB, D_AR, D_AB } Tdireccion;

struct posicion {
    char * palabra;
    size_t fila;
    size_t columna;
    Tdireccion direccion;
};

typedef struct{
    int di;
    int dj;
    Tdireccion direccion;
}tDir;

typedef struct posicion * tVecPosiciones;

tVecPosiciones resolverSopa(char m[FILS][COLS], char * diccionario[]);
tVecPosiciones addMemory(tVecPosiciones aux, int cant_elementos);
tVecPosiciones buscarDirecciones(tVecPosiciones aux, int * dim_aux, char * palabra, char sopa[FILS][COLS], int i_inicial, int j_inicial);
tVecPosiciones buscar_una_Direccion(tDir dir,int longitud_busqueda, tVecPosiciones aux, int * dim_aux, char * palabra, char sopa[FILS][COLS], int i_inicial, int j_inicial);
tVecPosiciones buscarPalabra(tVecPosiciones aux, int * dim_aux, char * palabra, char sopa[FILS][COLS]);
tVecPosiciones loadFound(Tdireccion dir,int i, int j, char * palabra, tVecPosiciones aux, int * dim_aux);

tVecPosiciones resolverSopa(char m[FILS][COLS], char * diccionario[]){
    tVecPosiciones aux = malloc(sizeof(struct posicion) * BLOQUE);  
    int dim_aux = 0;
    for(int i=0; *diccionario[i] != '\0'; i++){
        aux = buscarPalabra(aux, &dim_aux, diccionario[i], m);
    }
    aux = realloc(aux, (dim_aux+1) * sizeof(*aux)); // si uso addMemory, no va a tener lo minimo. Aca recorto. 
    struct posicion fin = {NULL, 0,0,0};
    aux[dim_aux] = fin;
    return aux;
}

tVecPosiciones buscarPalabra(tVecPosiciones aux, int * dim_aux, char * palabra, char sopa[FILS][COLS]){
    for(int i=0; i<FILS; i++){
        for(int j=0; j<COLS; j++){
            aux = buscarDirecciones(aux,dim_aux,palabra,sopa, i, j);
        }
    }
    return aux;
}

tVecPosiciones buscarDirecciones(tVecPosiciones aux, int * dim_aux, char * palabra, char sopa[FILS][COLS], int i_inicial, int j_inicial){
    tDir deltas[CANT_DIRECCIONES] = {{1,0,ABA}, {-1,0,ARR},{0,1,DER},{0,-1,IZQ},{1,1,D_AB},{-1,1,D_AR},{1,-1,I_AB},{-1,-1,I_AR}};
    int flag = palabra[0] == sopa[i_inicial][j_inicial];
    int longitud_busqueda = strlen(palabra);
    for(int k=0; flag && k<CANT_DIRECCIONES; k++){
        aux = buscar_una_Direccion(deltas[k], longitud_busqueda, aux, dim_aux, palabra, sopa, i_inicial, j_inicial);
    }
    return aux;
}

#define IN_RANGE(i,j) (i>= 0 && j>= 0 && i<FILS && j<COLS)
tVecPosiciones buscar_una_Direccion(tDir dir,int longitud_busqueda, tVecPosiciones aux, int * dim_aux, char * palabra, char sopa[FILS][COLS], int i_inicial, int j_inicial){
    for(int i = i_inicial, j = j_inicial, cant_letras_buscadas =0;  cant_letras_buscadas < longitud_busqueda; cant_letras_buscadas++, i+=dir.di, j+=dir.dj){
        if(!IN_RANGE(i,j) || palabra[cant_letras_buscadas] != sopa[i][j]){
            return aux; // no cambio nada. 
        }
    }
    aux = loadFound(dir.direccion, i_inicial, j_inicial, palabra, aux, dim_aux);
    return aux;
}

tVecPosiciones loadFound(Tdireccion dir,int i, int j, char * palabra, tVecPosiciones aux, int * dim_aux){
        aux = addMemory(aux, *dim_aux + 1);
        struct posicion cargar = {palabra, i, j, dir};
        aux[*dim_aux] = cargar;
        (*dim_aux)++;
    return aux;
}

tVecPosiciones addMemory(tVecPosiciones aux, int cant_elementos){
        if(cant_elementos % BLOQUE == 0){
            aux = realloc(aux, (BLOQUE + cant_elementos) * (sizeof(struct posicion)));
        }
        return aux;
}

Gracias de antemano, Luciano.

marcelogarberoglio commented 1 year ago

Está bien enviarlo como parámetro y que lo retorne, ya que asemeja el uso de realloc (le pasás lo que tenés y de ser necesario te retorna el nuevo puntero). Incluso en resolverSopa podés hacer como siempre: inicializar aux en NULL.

lulostupnik commented 1 year ago

Si lo inicializo en NULL, no estaria guardando en memoria que todavia no reserve la primera vez que se llama a la funcion loadFound?

Ya que esa funcion llama addMemory con parametro como cantidad de elementos en 1 (ya que dim_aux seria 0 y le mando siempre uno mas que la dimension). Y como 1%BLOQUE es diferente a 0, no se reservaria espacio.

marcelogarberoglio commented 1 year ago

Podrías hacer como hacemos siempre: primero hacés lugar y luego incrementás la dimensión.