Neste projeto, o objetivo foi, sobretudo, trabalhar com listas ligadas, uma primeira estrutura de armazenamento de dados. O laboratório visava ler um Dicionário com expressões típicas do cotidiano iteano, para gravar as informações em um vetor de listas ligadas através de uma função de dispersão. A função em questão foi, no caso, dada pela soma, em ASCII, dos caracteres de cada expressão a ser gravada. Tendo essas informações já gravadas no vetor, foi possível consultar expressões (função 2), inserir significados ainda não contidos na estrutura (função 3), eliminar significados com a ressalva de que, no caso de tal significado ser único, a expressão referente também deveria ser desalocada (função 4), eliminar expressões em si (função 5) e gerar uma nova base de dados, atualizada (função 6). Para ver o código em execução, assista ao vídeo abaixo.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
/********** DEFINEM-SE OS TYPEDEF'S E AS STRUCT'S **********/
typedef struct nodeSignificado nodeSignificado;
typedef struct nodeExpressao nodeExpressao;
typedef nodeExpressao *elementoVetor;
typedef nodeSignificado *acompanhanteSignificado;
typedef nodeExpressao *acompanhanteExpressao;
typedef int contador;
struct nodeSignificado
{
char significado[50];
nodeSignificado *prox;
};
struct nodeExpressao
{
char expressao[50];
nodeSignificado *listaSignificado;
nodeExpressao *prox;
};
/********** DEFINEM-SE AS FUNCOES AUXILIARES **********/
void zerarStrings(char expr[50], char signif[50], char aux[101])
{
/*** ZERA AS STRINGS AUXILIARES, I.E., AS CRIADAS NA MAIN ***/
contador i;
for(i=0; i<=49; i++)
{
expr[i] = '\0';
signif[i] = '\0';
aux[i] = '\0';
}
for(i=50; i<=100; i++)
aux[i] = '\0';
}
int obterASCII(char expr[50], int N)
{
/*** FAZ A SOMA, EM ASCII, DOS CARACTERES DAS EXPRESSOES ***/
contador i;
int ASCII = 0;
for(i=0; expr[i] != '\0'; i++)
ASCII += expr[i];
return ASCII %= N;
}
void inserirSignificado(elementoVetor *V, char expr[50], char signif[50], int N)
{
int ASCII = obterASCII(expr, N);
/*** CASO AINDA ESTEJA "NOVO", ALOCARA O nodeExpressao, o nodeSignificado E SALVA OS VALORES DE expr[50] e signif[50] ***/
if(V[ASCII] == NULL)
{
V[ASCII] = (nodeExpressao*) malloc (sizeof(nodeExpressao));
strcpy(V[ASCII]->expressao, expr);
V[ASCII]->prox = NULL;
V[ASCII]->listaSignificado = (nodeSignificado*) malloc (sizeof(nodeSignificado));
strcpy(V[ASCII]->listaSignificado->significado, signif);
V[ASCII]->listaSignificado->prox = NULL;
}
/*** CASO A PRIMEIRA EXPRESSAO SEJA A PROCURADA ***/
else if(strcmp(V[ASCII]->expressao, expr) == 0)
{
bool encontrouSignificado = false;
acompanhanteSignificado S;
S = V[ASCII]->listaSignificado;
///TESTARA OS SIGNIFICADOS TENTANDO ENCONTRA-LO
while(S->prox != NULL)
{
if(strcmp(S->significado, signif) == 0)
encontrouSignificado = true;
S = S->prox;
}
///TESTARA UMA ULTIMA TENTATIVA, JA QUE O LIMITE VAI ATE S->PROX E, LOGO, AGORA ESTA EM S
if(encontrouSignificado == false)
{
///CASO AGORA TENHA ENCONTRADO, ENTAO O SIGNIFICADO ESTA LA, E NAO SERA PRECISO FAZER NADA
if(strcmp(S->significado, signif) == 0)
{}
///CASO NAO TENHA ENCONTRADO, PRECISARA ADICIONAR ESSE SIGNIFICADO
else
{
S->prox = (nodeSignificado *) malloc (sizeof (nodeSignificado));
strcpy(S->prox->significado, signif);
S->prox->prox = NULL;
}
}
}
/*** CASO A PRIMEIRA EXPRESSAO NAO SEJA NECESSARIAMENTE, A PROCURADA ***/
else
{
bool encontrouExpressao = false;
acompanhanteExpressao E;
E = V[ASCII];
/*** PROCURA A EXPRESSAO ***/
while(E->prox != NULL) ///alteracao feita aqui..., antes era E != NULL
{
if(strcmp(V[ASCII]->expressao, expr) == 0)
{
encontrouExpressao = true;
bool encontrouSignificado = false;
acompanhanteSignificado S;
S = V[ASCII]->listaSignificado;
while(S->prox != NULL)
{
if(strcmp(S->significado, signif) == 0)
encontrouSignificado = true;
S = S->prox;
}
if(encontrouSignificado == false)
{
S = (nodeSignificado *) malloc (sizeof (nodeSignificado));
strcpy(S->significado, signif);
S->prox = NULL;
}
}
E = E->prox;
}
/*** CASO NAO A TENHA ENCONTRADO, TESTARA UMA ULTIMA VEZ ***/
if(encontrouExpressao == false)
{
if(strcmp(V[ASCII]->expressao, expr) == 0)
{
bool encontrouSignificado = false;
acompanhanteSignificado S;
S = V[ASCII]->listaSignificado;
while(S->prox != NULL)
{
if(strcmp(S->significado, signif) == 0)
encontrouSignificado = true;
S = S->prox;
}
if(encontrouSignificado == false)
{
S = (nodeSignificado *) malloc (sizeof (nodeSignificado));
strcpy(S->significado, signif);
S->prox = NULL;
}
}
else
{
E = (nodeExpressao*)malloc(sizeof(nodeExpressao));
strcpy(E->expressao, expr);
E->listaSignificado = (nodeSignificado*)malloc(sizeof(nodeSignificado));
strcpy(E->listaSignificado->significado, signif);
E->prox = NULL;
E->listaSignificado->prox = NULL;
}
}
}
}
void eliminarSignificado(elementoVetor *V, char expr[50], char signif[50], int N)
{
int ASCII = obterASCII(expr, N);
acompanhanteExpressao E;
E = V[ASCII];
/*** CASO A EXPRESSAO QUE CONTEM O SIGNIFICADO A SER ELIMINADO SEJA (A EXPRESSAO) LOGO A PRIMEIRA ***/
if(strcmp(E->expressao, expr) == 0)
{
acompanhanteSignificado S;
S = E->listaSignificado;
///CASO O SIGNIFICADO A SER ELIMINADO SEJA LOGO O PRIMEIRO
if(strcmp(S->significado, signif) == 0)
{
/// CASO ESSE SIGNIFICADO SEJA UNICO
if(S->prox == NULL)
{
if(V[ASCII]->prox == NULL)
V[ASCII] = NULL;
else
{
V[ASCII] = V[ASCII]->prox;
free(E);
}
}
/// CASO ESSE SIGNIFICADO SEJA O PRIMEIRO, MAS NAO SEJA O UNICO QUE A EXPRESSAO APRESENTA
else
{
E->listaSignificado = E->listaSignificado->prox;
S->prox = NULL;
free(S);
}
}
/// CASO O SIGNIFICADO DA EXPRESSAO NAO SEJA O PRIMEIRO
while(S->prox->prox != NULL)
{
if(strcmp(S->significado, signif) == 0)
{
acompanhanteSignificado T;
T = S;
S = S->prox;
free(T);
}
else
S = S->prox;
}
/// SE ESSE SIGNIFICADO FOR O PENULTIMO
if(strcmp(S->significado, signif) == 0)
{
acompanhanteSignificado T;
T = S;
S = S->prox;
free(T);
}
/// SE ESSE SIGNIFICADO FOR O ULTIMO
else if(strcmp(S->prox->significado, signif) == 0)
{
acompanhanteSignificado T;
T = S->prox;
S->prox = S->prox->prox; //NULL
free(T);
}
}
/*** CASO A EXPRESSAO NAO SEJA, NECESSARIAMENTE, A PRIMEIRA ***/
else
{
bool encontrouExpressao = false;
while((E->prox != NULL) && (encontrouExpressao == false))
{
if(strcmp(E->expressao, expr) == 0)
encontrouExpressao = true;
else
E = E->prox;
}
if(encontrouExpressao == true)
{
acompanhanteExpressao F;
F = E;
acompanhanteSignificado S;
S = E->listaSignificado;
if(strcmp(S->significado, signif) == 0)
{
///CASO SEJA O PRIMEIRO E UNICO SIGNIFICADO, PRECISARA DESALOCAR A EXPRESSAO, TAMBEM
if(S->prox == NULL)
{
E = E->prox;
free(F->listaSignificado);
free(F);
}
else
{
E->listaSignificado = E->listaSignificado->prox;
free(S);
}
}
while(S->prox != NULL)
{
if(strcmp(S->significado, signif) == 0)
{
acompanhanteSignificado T;
T = S;
S = S->prox;
free(T);
}
else
S = S->prox;
}
if(strcmp(S->significado, signif) == 0)
{
acompanhanteSignificado T;
T = S;
S = S->prox;
free(T);
}
else if(strcmp(S->prox->significado, signif) == 0)
{
acompanhanteSignificado T;
T = S->prox;
S->prox = S->prox->prox;
free(T);
}
}
}
}
void eliminarExpressao(elementoVetor *V, char expr[50], int N)
{
int ASCII = obterASCII(expr, N);
acompanhanteExpressao E, F;
E = F = V[ASCII];
/*** CASO A EXPRESSAO A SER ELIMINADA FOR A PRIMEIRA ***/
if(strcmp(E->expressao, expr) == 0)
{
if(E->prox == NULL)
{
if(V[ASCII]->prox == NULL)
V[ASCII] = NULL;
else
{
V[ASCII] = V[ASCII]->prox;
free(E);
}
}
else
{
E = E->prox;
F->prox = NULL;
free(F);
}
}
else
{
bool encontrouExpressao = false;
while((E->prox != NULL)&&(encontrouExpressao == false))
{
if(strcmp(E->expressao, expr) == 0)
encontrouExpressao = true;
else
E = E->prox;
}
if(encontrouExpressao == false)
{
if(strcmp(E->expressao, expr) == 0)
encontrouExpressao = true;
}
if(encontrouExpressao == true)
{
acompanhanteSignificado S, T;
S = T = E->listaSignificado;
while(S != NULL)
{
T = S;
S = S->prox;
free(T);
}
F = E;
E = E->prox;
free(F);
}
}
}
/*** MAIN ***/
int main()
{
/*** ABRE OS ARQUIVOS DE ENTRADA E SAIDA ***/
FILE *arqEntrada, *arqSaida;
arqEntrada = fopen("entrada.txt", "r");
arqSaida = fopen("saida.txt", "w");
/*** VARIAVEIS DO PROGRAMA ***/
char expr[50], signif[50], aux[101], *pch, lixo;
int N, qtdOperac, codOperac;
contador i, j;
/*** ALOCAR VETOR ***/
fscanf(arqEntrada, "%d", &N);
nodeExpressao **V;
V = (elementoVetor*) malloc (N * sizeof (elementoVetor*));
/*** APONTAR OS ELEMENTOS DO VETOR PARA NULL ***/
for(i=0; i<=N-1; i++)
V[i] = NULL;
/*** LOOP PRINCIPAL ***/
fscanf(arqEntrada, "%d", &qtdOperac);
for(i=1; i<=qtdOperac; i++)
{
zerarStrings(expr, signif, aux);
fscanf(arqEntrada, "%d%c", &codOperac, &lixo);
switch(codOperac)
{
/*** ABRE A ESTRUTURA DE DADOS E INSERE OS DADOS NO VETOR ***/
case 1:
{
FILE *arqLeitura;
arqLeitura = fopen("DicionITA.txt", "r");
while(fgets(aux, 101, arqLeitura) != NULL)
{
aux[strlen(aux)-1] = '\0';
pch = strtok(aux, "|");
strcpy(expr, pch);
pch = strtok(NULL, "|");
strcpy(signif, pch);
inserirSignificado(V, expr, signif, N);
zerarStrings(expr, signif, aux);
}
fclose(arqLeitura);
}
break;
/*** CONSULTA UMA EXPRESSAO PELOS SEUS SIGNIFICADOS ***/
case 2:
{
fgets(expr, 50, arqEntrada);
expr[strlen(expr)-1] = '\0';
int ASCII = obterASCII(expr, N);
acompanhanteExpressao E;
E = V[ASCII];
bool encontrouExpressao = false;
while((E != NULL) && (encontrouExpressao == false))
{
if(strcmp(E->expressao, expr) == 0)
encontrouExpressao = true;
else
E = E->prox;
}
if(encontrouExpressao == true)
{
acompanhanteSignificado S;
S = V[ASCII]->listaSignificado;
while(S != NULL)
{
fprintf(arqSaida, "%s\n", S->significado);
S = S->prox;
}
fprintf(arqSaida, "\n");
}
else
fprintf(arqSaida, "nada consta\n\n");
}
break;
/*** ACRESCENTA, CASO AINDA NAO ESTEJA PRESENTE, UM SIGNIFICADO A ALGUMA EXPRESSAO ***/
case 3:
{
fgets(aux, 101, arqEntrada);
aux[strlen(aux)-1] = '\0';
pch = strtok(aux, "|");
strcpy(expr, pch);
pch = strtok(NULL, "|");
strcpy(signif, pch);
inserirSignificado(V, expr, signif, N);
}
break;
/*** ELIMINA UM SIGNIFICADO, CASO ESTEJA PRESENTE ***/
case 4:
{
fgets(aux, 101, arqEntrada);
aux[strlen(aux)-1] = '\0';
char *pch;
pch = strtok(aux, "|");
strcpy(expr, pch);
pch = strtok(NULL, "|");
strcpy(signif, pch);
eliminarSignificado(V, expr, signif, N);
}
break;
/*** ELIMINA UMA EXPRESSAO, CASO ESTEJA PRESENTE ***/
case 5:
{
fgets(expr, 50, arqEntrada);
expr[strlen(expr)-1] = '\0';
eliminarExpressao(V, expr, N);
}
break;
/*** PRODUZ A NOVA ESTRUTURA DE DADOS ***/
case 6:
{
FILE *DicionITA;
DicionITA = fopen("Dicionario.txt", "w");
acompanhanteExpressao E = V[0];
acompanhanteSignificado S = V[0]->listaSignificado;
for(j=0; j <= N-1; j++)
{
if(V[j] != NULL)
{
E = V[j];
S = V[j]->listaSignificado;
while(E != NULL)
{
while(S != NULL)
{
fprintf(DicionITA, "%s|%s\n", E->expressao, S->significado);
S = S->prox;
}
E = E->prox;
}
}
}
fprintf(DicionITA, "\n");
fclose(DicionITA);
}
break;
default:
{
fprintf(arqSaida,"ERRO\n\n");
return 0;
}
break;
}
}
fclose(arqEntrada);
fclose(arqSaida);
return 0;
}
Nenhum comentário:
Postar um comentário