/*** ALUNO: GUSTAVO NAHUM ALVAREZ FERREIRA ***/
/*** TURMA: 19.3 ***/
/*** LAB 3 - CES 11 ***/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
/** O MÁXIMO É REFERENTE À QUANTIDADE DE ELEMENTOS DA STRING QUE RECEBERÁ AS LINHAS DE "entrada.txt" **/
#define max 100
/** AS DUAS ESTRUTURAS DE DADOS USADAS NO CÓDIGO FORAM A árvore, A PARTIR DE células, E A pilha, A PARTIR DE nodes. A árvore SERÁ NECESSÁRIA AO LONGO DE TODO O CÓDIGO **/
typedef struct celula celula;
struct celula
{
char letra;
int cont;
celula *filhos[26];
};
typedef celula *arvore;
typedef celula *posicao;
/** A pilha SERÁ IMPORTANTE PARA AUXILIAR NA IMPRESSÃO DAS PALAVRAS CONTIDAS NA árvore **/
typedef struct node node;
struct node
{
char elem;
node *prox;
};
typedef node *pilha;
/** A FUNÇÃO "alocaArvore" CRIA O "NÓ-LÍDER" DA árvore, E APONTA PARA AS LETRAS INICIAIS DAS PALAVRAS. ELA SERÁ USADA NA "main", PARA ALOCAR A árvore USADA EM TODO O PROGRAMA **/
void alocaArvore (arvore *A)
{
(*A) = (celula *)malloc(sizeof(celula));
(*A)->letra = '#';
(*A)->cont = 0;
int i;
for(i = 0; i <= 25; i++)
(*A)->filhos[i] = NULL;
}
/** A FUNÇÃO "alocaCelula" CRIA UMA NOVA célula E INSERE A LETRA CORRESPONDENTE. ELA SERÁ USADA EM "lerArquivo", NA HORA DE INSERIR AS LETRAS DAS PALAVRAS **/
void alocaCelula (celula **P, char c)
{
(*P) = (celula *)malloc(sizeof(celula));
(*P)->letra = c;
(*P)->cont = 0;
int i;
for(i = 0; i <= 25; i++)
(*P)->filhos[i] = NULL;
}
/** A FUNÇÃO "numFilhos" RETORNA O VALOR NUMÉRICO CORRESPONDENTE A UMA LETRA DADA: "a" E "A" CORRESPONDEM AO "0", "b" E "B" CORRESPONDEM AO "1", ETC. ELA SERÁ IMPORTANTE PARA FACILITAR A CONVERSÃO DE MAIÚSCULAS EM MINÚSCULAS EM "lerArquivo" **/
int numFilhos(char carac)
{
if(islower(carac))
return carac - 'a';
else
return carac - 'A';
}
/** A FUNÇÃO "lerArquivo" DEVERÁ LER O ARQUIVO "entrada.txt" E GERAR A árvore CORRESPONDENTE. COM ESSA árvore, A FUNÇÃO "imprimirArquivo" PODERÁ IMPRIMIR AS PALAVRAS E SUAS QUANTIDADES DE APARIÇÃO EM "entrada.txt" **/
void lerArquivo(FILE *f_entrada, arvore *A)
{
char string[max];
int i, aux;
posicao P;
P = *A;
while(fgets(string, max, f_entrada) != NULL) /* RECEBE, LINHA A LINHA, O CONTEÚDO DE "entrada.txt" */
{
for(i = 0; i <= strlen(string)-1; i++) /* ANALISA, LETRA A LETRA, O CONTEÚDO DAS LINHAS: */
{
if(isalpha(string[i])) /* 1. SE FOR ALFA-NUMÉRICO, A LETRA VAI PARA A PRÓXIMA CÉLULA */
{
if(P->filhos[numFilhos(string[i])] == NULL)
alocaCelula(&P->filhos[numFilhos(string[i])], numFilhos(string[i])+'a');
P = P->filhos[numFilhos(string[i])];
}
else /* 2. SE NÃO FOR ALFA-NUMÉRICO, A CÉLULA INCREMENTA O CONTADOR... */
{ /* ...E RETORNA AO TOPO DA ÁRVORE, PARA INICIAR A LEITURA DE UMA NOVA PALAVRA */
P->cont++;
P = *A;
}
}
}
}
/** A FUNÇÃO "tamanhoPilha" RETORNA A QUANTIDADE DE nodes DA pilha. ELA SERÁ USADA PARA AUXILIAR A FUNÇÃO "imprimePilhaReversa" **/
int tamanhoPilha(pilha P)
{
int i;
node *Q;
Q = P;
for (i = 0; Q != NULL; Q = Q->prox)
i++;
return i;
}
/** A FUNÇÃO "imprimePilhaReversa" IMPRIME OS VALORES DA pilha, DO ÚLTIMO PARA O PRIMEIRO ELEMENTO. ELA SERÁ USADA NA FUNÇÃO "imprimeArquivo" **/
void imprimePilhaReversa(FILE *f_saida, pilha P)
{
int i, j;
node *Q;
for(j = tamanhoPilha(P); j>= 1; j--)
{
Q = P;
for(i = 1; i < j; i++)
Q = Q->prox;
fprintf(f_saida, "%c", Q->elem);
}
fprintf(f_saida, "\n");
}
/** A FUNÇÃO RECURSIVA "imprimeArquivo" TOMA A árvore PRODUZIDA EM "lerArquivo" E USA UMA PILHA QUE É ALTERADA CONTINUAMENTE. ESSA pilha SERVE PARA GUARDAR AS PALAVRAS QUE SERÃO IMPRESSAS EM "saida.txt" **/
void imprimeArquivo (FILE *f_saida, posicao A, pilha *P)
{
int i;
for(i = 0; i <= 25; i++) /* PERCORRERÁ OS CAMPOS filhos[i], PARA ENCONTRAR POSSÍVEIS CONTINUAÇÕES PARA AS PALAVRAS */
{
if(A->filhos[i] != NULL) /* SE HOUVER CONTINUAÇÃO, ELA É INSERIDA NA pilha */
{
node *Q;
Q = (node *)malloc(sizeof(node));
Q->elem = A->filhos[i]->letra;
Q->prox = *P;
*P = Q;
if(A->filhos[i]->cont != 0) /* SE HOUVER UMA PALAVRA ATÉ ALI, ELA SERÁ IMPRESSA EM "saida.txt" */
{
fprintf(f_saida, "%d ", A->filhos[i]->cont);
imprimePilhaReversa(f_saida, *P);
}
imprimeArquivo(f_saida, A->filhos[i], P); /* E, RECURSIVAMENTE, ELA FARÁ ISSO COM TODOS OS SEUS FILHOS "NÃO-NULLOS" */
}
}
if(*P != NULL) /* AO FINAL, DESALOCA-SE O node CORRESPONDENTE À LETRA CORRESPONDENTE A ESTE ESCOPO DA FUNÇÃO */
{
node *D;
D = (*P)->prox;
free(*P);
*P = D;
}
}
int main()
{
arvore A; A = NULL; alocaArvore(&A);
pilha P; P = NULL;
FILE *f_entrada, *f_saida;
f_entrada = fopen("entrada.txt", "r");
f_saida = fopen("saida.txt", "w");
lerArquivo(f_entrada, &A);
imprimeArquivo(f_saida, A, &P);
fclose(f_entrada);
fclose(f_saida);
return 0;
}
domingo, 25 de outubro de 2015
LAB 3 - CES 11
Olá! Agora apresento o meu código para o LAB 3 de CES 11. Nele, o objetivo era o de criar um contador de palavras, a partir da implementação da estrutura de dados árvore. Para auxiliar nesse trabalho, também foi implementada uma pilha de caracteres alocada dinamicamente, facilitando a impressão das palavras. Acompanhe o vídeo abaixo e, a seguir, veja o código comentado:
segunda-feira, 5 de outubro de 2015
Questão 4 da prova de CES11:
typedef struct node node;
struct node{
int num;
node *fesq, *fdir;
};
typedef node *arvore;
arvore A;
void imprimeMultiplosde5 (arvore A)
{
if(A != NULL)
{
if(A->fesq != NULL)
{
if(A->fesq->fesq != NULL)
{
if(A->num%5 == 0)
printf("%d\n", A->fesq->fesq->num);
}
if(A->fesq->fdir != NULL)
{
if(A->num%5 == 0)
printf("%d\n", A->fesq->fdir->num);
}
imprimeMultiplosde5(A->fesq);
}
if(A->fdir != NULL)
{
if(A->fdir->fesq != NULL)
{
if(A->num%5 == 0)
printf("%d\n", A->fdir->fesq->num);
}
if(A->fdir->fdir != NULL)
{
if(A->num%5 == 0)
printf("%d\n", A->fdir->fdir->num);
}
imprimeMultiplosde5(A->fdir);
}
}
}
Assinar:
Comentários (Atom)