terça-feira, 15 de setembro de 2015

ATIVIDADE DE LABORATÓRIO 2 - DICIONÁRIO ITEANO

https://www.youtube.com/watch?v=JuTiypw0_ks&feature=youtu.be Dando continuidade as atividades laboratoriais da disciplina de ces-11 do Prof. Yano, segue o código fonte da atividade 2, o dicionário iteano. Com essa atividade foi possível um primeiro contato com estruturas de dados em geral, em particular com as tabelas de dispersão(hash-tables), além de relembrar conceitos importantes de lista ligada e alocação dinâmica. Vale lembrar que foi imporatnte devido ao alto uso de ponteiros.

Link para o vídeo : https://www.youtube.com/watch?v=JuTiypw0_ks&feature=youtu.be

Segue o código fonte:

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


typedef struct nodeSignificado nodeSignificado;
typedef struct nodeExpressao nodeExpressao;

struct nodeSignificado
{
    char signif[50];
    nodeSignificado *prox;
};
struct nodeExpressao
{
    char expr[50];
    nodeSignificado *listaSignificado;
    nodeExpressao *prox;
};///declarações
typedef struct nodeExpressao *vetor;
typedef vetor *vetor_ponteiros;

void EliminarExpressao(vetor_ponteiros L, char *expr, int N);
void InserirSignificado(vetor_ponteiros L, int N, char *expr, char *sign);
void Ler_Linha(char *linha, char *expr, char *sign);
vetor_ponteiros CarregarDados(FILE *arqEntrada, int N);
void ConsultarExpressao(char *expr, vetor_ponteiros L, int N, FILE *arqSaida);
void InserirSignificado(vetor_ponteiros L, char *expr, char *novo_signif, int N);
void ElimiarSignificado(vetor_ponteiros L, char* expr, char *signif, int N);
void EliminarExpressao(vetor_ponteiros L, char *expr, int N);
void GerarBaseDados(vetor_ponteiros L, int N, FILE *arqSaida);




void InserirSignificado(vetor_ponteiros L, int N, char *expr, char *sign)
{
    int hash = 0;
    for(int i = 0; expr[i] !='\0'; i++)
    {
        hash += expr[i];
    }
    hash = hash % N;

    vetor p = L[hash];
    if(p == NULL)  ///hash vazio
    {
        L[hash] = (nodeExpressao*)malloc(sizeof(nodeExpressao));
        p = L[hash];
        p->prox = NULL;
        strcpy(p->expr, expr);
        p->listaSignificado = (nodeSignificado*)malloc(sizeof(nodeSignificado));
        strcpy(p->listaSignificado->signif, sign);
        p->listaSignificado->prox = NULL;
    }
    else  ///hash já ocupado
    {
        vetor aux = p;
        bool state = true;

        while(p != NULL && state)
        {
            if(strcmp(p->expr, expr))
            {
                aux = p;
                p = p->prox;
            }
            else
                state = false;
        }

        if(p == NULL)  ///Não existe a expressão
        {
            aux->prox = (nodeExpressao*)malloc(sizeof(nodeExpressao));
            p = aux->prox;
            p->prox = NULL;
            p->listaSignificado = (nodeSignificado*)malloc(sizeof(nodeSignificado));
            strcpy(p->listaSignificado->signif, sign);
            p->listaSignificado->prox = NULL;
        }
        else  ///Já existe a expressão
        {
            nodeSignificado *q = p->listaSignificado, *r;
            bool state = true;

            while(q != NULL && state)
            {
                if(strcmp(q->signif, sign))
                {
                    r = q;
                    q = q->prox;
                }
                else
                    state = false;
            }

            if(q == NULL)  ///significado ainda não existe
            {
                r->prox = (nodeSignificado*)malloc(sizeof(nodeSignificado));
                r = r->prox;
                r->prox = NULL;
                strcpy(r->signif, sign);
            }
        }
    }
}
void Ler_Linha(char *linha, char *expr, char *sign)
{
    char *pch;
    linha[strlen(linha) - 1] = '\0';
    pch = strtok(linha,"|");
    strcpy(expr, pch);
    pch = strtok(NULL,"|");
    strcpy(sign,pch);
}
vetor_ponteiros CarregarDados(FILE *arqEntrada, int N)
{
    vetor_ponteiros L = new vetor[N];
    char linha[100];
    for(int i = 0; i < N; i++)
        L[i] = NULL;

    while(fgets(linha, 100, arqEntrada) != NULL)
    {
        char expr[50], sign[50];
        Ler_Linha(linha, expr, sign);
        InserirSignificado(L, N, expr, sign);
    }

    return L;
}

void ConsultarExpressao(char *expr, vetor_ponteiros L, int N, FILE *arqSaida)///função numero 2
{
    int hash = 0;
    for(int i = 0; expr[i] != '\0'; i++)
    {
        hash += expr[i];
    }
    hash = hash % N;
    vetor p = L[hash];
    if(p)
    {
        bool state = true;
        while(p && state)
        {
            if(strcmp(p->expr, expr))
            {
                p = p->prox;
            }
            else
                state = false;
        }
        if(!state)
        {
            nodeSignificado *q = p->listaSignificado;
            while(q)
            {
                fprintf(arqSaida, "%s\n", q->signif);
                q = q->prox;
            }
            fprintf(arqSaida, "\n");
        }
        else
        {
            fprintf(arqSaida,"nada consta\n");
        }
    }
    else
        fprintf(arqSaida,"nada consta\n");
}
void InserirSignificado(vetor_ponteiros L, char *expr, char *novo_signif, int N)///função numero 3
{
    int hash = 0;
    for(int i = 0; expr[i] != '\0'; i++)
    {
        hash += expr[i];
    }
    hash = hash % N;

    vetor p = L[hash];
    if(p == NULL)  ///hash vazia
    {
        L[hash] = (nodeExpressao*)malloc(sizeof(nodeExpressao));
        p = L[hash];
        p->prox = NULL;
        strcpy(p->expr, expr);
        p->listaSignificado = (nodeSignificado*)malloc(sizeof(nodeSignificado));
        strcpy(p->listaSignificado->signif, novo_signif);
        p->listaSignificado->prox = NULL;
    }
    else  ///Colisão ou significado existe
    {
        vetor aux = p;
        bool estado = true;

        while(p != NULL && estado)
        {
            if(strcmp(p->expr, expr))
            {
                aux = p;
                p = p->prox;
            }
            else
                estado = false;
        }

        if(p == NULL)  ///Ainda não existe expressão
        {
            aux->prox = (nodeExpressao*)malloc(sizeof(nodeExpressao));
            p = aux->prox;
            p->prox = NULL;
            p->listaSignificado = (nodeSignificado*)malloc(sizeof(nodeSignificado));
            strcpy(p->listaSignificado->signif, novo_signif);
            p->listaSignificado->prox = NULL;
        }
        else  ///Expressão já existente
        {
            nodeSignificado *q = p->listaSignificado, *r;
            bool estado = true;

            while(q != NULL && estado)
            {
                if(strcmp(q->signif, novo_signif))
                {
                    r = q;
                    q = q->prox;
                }
                else
                    estado = false;
            }

            if(q == NULL)  /// Significado não existe
            {
                r->prox = (nodeSignificado*)malloc(sizeof(nodeSignificado));
                r = r->prox;
                r->prox = NULL;
                strcpy(r->signif, novo_signif);
            }
        }
    }
}

void ElimiarSignificado(vetor_ponteiros L, char* expr, char *signif, int N)///função numero 4
{
    int hash = 0;

    for(int i = 0; expr[i] !='\0'; i++)
        hash += expr[i];
    hash = hash % N;
    vetor p = L[hash];
    bool estado = true;

    while(p && estado)
    {
        if(strcmp(p->expr, expr))
        {
            p = p->prox;
        }
        else
            estado = false;
    }

    if(!estado)  /// Expressão existe
    {
        nodeSignificado *r = p->listaSignificado, *s = NULL;
        bool estado = true;

        while(r && estado)
        {
            if(strcmp(r->signif, signif))
            {
                s = r;
                r = r->prox;
            }
            else
                estado = false;
        }

        if(!estado)  ///significado a ser eliminado
        {
            if(!s)  /// Primeiro significado da listaSignificado
            {
                if(!(r->prox)) ///Um significado
                    EliminarExpressao(L, expr, N);
                else
                {
                    p->listaSignificado = r->prox;
                    free(r);
                }
            }
            else
            {
                s->prox = r->prox;
                free(r);
            }
        }
    }
}

void EliminarExpressao(vetor_ponteiros L, char *expr, int N)///função numero 5
{
    int hash = 0;
    for(int i = 0; expr[i] !='\0'; i++)
        hash += expr[i];
    hash = hash % N;

    vetor p = L[hash], q = NULL;
    bool estado = true;
    while(p && estado)
    {
        if(strcmp(p->expr, expr))
        {
            q = p;
            p = p->prox;
        }
        else
            estado = false;
    }

    if(!estado)
    {
        nodeSignificado *r = p->listaSignificado, *s;
        while(r)
        {
            s = r;
            r = r->prox;
            free(s);
        }

        if(q)  /// Não é a primeira expressão da lista
        {
            q->prox = p->prox;
        }
        else  /// É a primeira da lista de expressões
        {
            L[hash] = p->prox;
        }

        free(p);
    }
}

void GerarBaseDados(vetor_ponteiros L, int N, FILE *arqSaida)///função numero 6
{
    int i = 0;
    vetor p, q;
    for(i = 0; i < N; i++)
    {
        p = L[i];
        while(p)
        {
            nodeSignificado *r = p->listaSignificado, *s;
            while(r)
            {
                fprintf(arqSaida, "%s|%s\n", p->expr, r->signif);
                s = r;
                r = r->prox;
                free(s);
            }
            q = p;
            p = p->prox;
            free(q);
        }
    }
    free(L);
}
int main ()
{

    FILE *arqEntrada1,*arqEntrada2, *teste, *arqSaida;
    vetor_ponteiros L;
    int N, n_operacoes, codigo = 0;
    char expr[50], signif[50], lixo,aux[200];
    char *pch;
    arqEntrada1 = fopen("entrada.txt","r");
    arqEntrada2 = fopen("DicionITA.txt", "r");
    arqSaida = fopen("saida.txt","w");
    fscanf(arqEntrada1,"%d",&N);
    fscanf(arqEntrada1,"%d",&n_operacoes);
    while(n_operacoes > 0)
    {
        fscanf(arqEntrada1,"%d%c", &codigo,&lixo);
        switch(codigo)
        {
        case 1:
            L = CarregarDados(arqEntrada2, N);
            fclose(arqEntrada2);
            teste = fopen("DicionITA.txt","w");
            break;
        case 2:
            fscanf(arqEntrada1,"%s", expr);
            ConsultarExpressao(expr,L, N, arqSaida);
            break;
        case 3:
            fgets(aux,101,arqEntrada1);
            aux[strlen(aux)-1]='\0';
            pch = strtok(aux,"|");
            strcpy(expr,pch);
            pch = strtok(NULL,"|");
            strcpy(signif,pch);
            InserirSignificado(L, expr, signif, N);
            break;
        case 4:
            fgets(aux,101,arqEntrada1);
            aux[strlen(aux)-1]='\0';
            pch = strtok(aux,"|");
            strcpy(expr,pch);
            pch = strtok(NULL,"|");
            strcpy(signif,pch);
            ElimiarSignificado(L, expr, signif, N);
            break;
        case 5:
            fscanf(arqEntrada1, "%s", expr);
            EliminarExpressao(L, expr, N);
            break;
        case 6:
            GerarBaseDados(L, N, teste);
            break;
        }
        n_operacoes--;
    }
    fclose(arqEntrada1);
    fclose(teste);
    fclose(arqSaida);

    return 0;
}