#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define INFINITO 1000000
typedef int vertice;
typedef struct CelAdj CelAdj;
struct CelAdj
{
vertice vert;
int minutos;
CelAdj *prox;
};
typedef struct CelVert CelVert;
struct CelVert
{
char aeroporto[30];
CelAdj *listaAdj;
};
typedef struct digrafo digrafo;
struct digrafo
{
int nvert;
CelVert *vertices;
};
typedef struct node node;
struct node
{
int vertice;
node *prox;
};
typedef node *pilha;
typedef node *posicao;
void BubbleSort (digrafo *G)
{
//EXECUTA 'BUBBLE-SORT' NAS LISTAS ADJACENTES DO DIGRAFO G
int i, vert_aux, minutos_aux;
CelAdj *P;
bool mudou = true;
for(i = 0; i <= G->nvert-1; i++)
{
P = G->vertices[i].listaAdj;
while(mudou == true)
{
mudou = false;
P = G->vertices[i].listaAdj;
while(P->prox != NULL)
{
if(P->vert > P->prox->vert)
{
vert_aux = P->vert;
minutos_aux = P->minutos;
P->vert = P->prox->vert;
P->minutos = P->prox->minutos;
P->prox->vert = vert_aux;
P->prox->minutos = minutos_aux;
mudou = true;
}
P = P->prox;
}
}
}
}
int Dijkstra(digrafo G, int ref, int desc, vertice parent[], vertice dist[])
{
vertice v, w, v_aux, w_aux;
CelAdj *P;
for (w = 0; w <= G.nvert-1; w++)
{
parent[w] = -1;
dist[w] = INFINITO;
}
parent[ref] = ref;
dist[ref] = 0;
while (1)
{
//EXECUTA O LOOP ENQUANTO ALGUMA DISTANCIA SOFRE ALTERACAO, TODA VEZ QUE SE PERCORRE O DIGRAFO
int min_dist = INFINITO;
for (v = 0; v <= G.nvert-1; v++)
if (parent[v] != -1)
for (P = G.vertices[v].listaAdj; P != NULL; P = P->prox)
if (parent[P->vert] == -1 && min_dist > dist[v] + P->minutos)
{
min_dist = dist[v] + P->minutos;
v_aux = v;
w_aux = P->vert;
}
if (min_dist == INFINITO)
break;
parent[w_aux] = v_aux;
dist[w_aux] = min_dist;
}
return dist[desc];
}
void push (pilha *P, vertice v)
{
node *temp;
temp = *P;
*P = (node *) malloc (sizeof (node));
(*P)->vertice = v;
(*P)->prox = temp;
}
void pop (pilha *P)
{
node *temp;
temp = *P;
*P = (*P)->prox;
free (temp);
}
void DFS(vertice v, bool *aciclico, vertice *expl, vertice *comp, pilha *P, int *ce, int *cc, digrafo G, FILE *f_saida)
{
expl[v] = ++(*ce);
push(P,v);
CelAdj *Q;
for(Q = G.vertices[v].listaAdj; Q != NULL; Q = Q->prox)
if(expl[Q->vert] == 0) //CASO AINDA NAO TENHA SIDO EXPLORADO, ENTRA NESSE VERTICE
DFS(Q->vert, aciclico, expl, comp, P, ce, cc, G, f_saida);
else if (expl[Q->vert] < expl[v] && comp[Q->vert]==0)
{
//CASO SEJA UMA ARESTA DE RETORNO (B), MOSTRA CILICIDADE, E IMPRIME O CICLO
*aciclico = false;
int j, tamanho_pilha = 0;
posicao T, F;
T = *P;
while(T->prox != NULL)
{
T = T->prox;
tamanho_pilha++;
}
F = T;
while(tamanho_pilha >= 0)
{
for(j = tamanho_pilha, T = *P; j >= 1; j--)
T = T->prox;
fprintf(f_saida, "%d-", T->vertice);
tamanho_pilha--;
}
fprintf(f_saida, "%d\n", F->vertice);
}
pop(P);
comp[v] = ++(*cc);
}
void Ciclos (digrafo G, vertice *expl, vertice *comp, FILE *f_saida)
{
pilha P;
P = NULL;
bool aciclico = true;
int ce = 0, cc = 0;
vertice v;
for (v = 0; v <= G.nvert-1; v++)
{
expl[v] = 0;
comp[v] = 0;
}
for (v = 0; v <= G.nvert-1; v++)
if (expl[v] == 0)
DFS(v, &aciclico, expl, comp, &P, &ce, &cc, G, f_saida);
}
int main()
{
digrafo G;
FILE *f_entrada, *f_saida;
f_entrada = fopen("entrada.txt", "r");
f_saida = fopen("saida.txt", "w");
int i;
/** RECEBE OS VERTICES **/
char aeroporto[31], lixo;
fscanf(f_entrada, "%d%c", &G.nvert, &lixo);
G.vertices = (CelVert *)malloc(G.nvert * sizeof(CelVert));
for(i = 0; i <= G.nvert-1; i++)
G.vertices[i].listaAdj = NULL; //ZERA TODAS AS LISTAS ADJACENTES
for(i = 0; i <= G.nvert-1; i++)
{
fgets(aeroporto, 31, f_entrada);
aeroporto[strlen(aeroporto)-1] = '\0'; //TIRA O '\N' DO FINAL DA STRING
strcpy(G.vertices[i].aeroporto, aeroporto); //PASSA O NOME PARA O DIGRAFO
}
/** RECEBE OS ARCOS **/
int quant_arcos;
fscanf(f_entrada, "%d", &quant_arcos);
int pred, suc, custo;
CelAdj *P;
for(i = 1; i <= quant_arcos; i++)
{
fscanf(f_entrada, "%d %d %d", &pred, &suc, &custo);
if(G.vertices[pred].listaAdj == NULL) //INICIA A LISTA ADJACENTE DE 'PRED'
{
P = G.vertices[pred].listaAdj = (CelAdj *)malloc(sizeof(CelAdj));
P->vert = suc;
P->minutos = custo;
P->prox = NULL;
}
else //CONTINUA A LISTA ADJACENTE JA INICIADA
{
P->prox = (CelAdj *)malloc(sizeof(CelAdj));
P = P->prox;
P->vert = suc;
P->minutos = custo;
P->prox = NULL;
}
}
BubbleSort(&G); //ORDENA AS LISTAS DE ADJACENCIAS
fprintf(f_saida ,"Digrafo:\n");
for(i = 0; i <= G.nvert-1; i++)
{
fprintf(f_saida, "%d (%s):", i, G.vertices[i].aeroporto);
P = G.vertices[i].listaAdj;
while(P != NULL)
{
fprintf(f_saida, " %d(%d)", P->vert, P->minutos);
P = P->prox;
}
fprintf(f_saida, "\n");
}
fprintf(f_saida, "\n");
/** CONSULTAS DE ROTAS MINIMAS **/
fprintf(f_saida, "Rotas minimas:\n");
int c, partida, chegada, dist_esp; //CONSULTA DE ROTAS MINIMAS
vertice *dist; //VETOR DE PONTEIROS PARA INT
vertice *parent; //VETOR DE PAIS DE UM VERTICE
vertice vert, filho;
dist = (vertice *)malloc(G.nvert * sizeof(vertice));
parent = (vertice *)malloc(G.nvert * sizeof(vertice));
fscanf(f_entrada, "%d", &c);
for(i = 1; i <= c; i++) //PARA CADA 'C', EXECUTA O ALG. DIJKSTRA
{
fscanf(f_entrada, "%d %d", &partida, &chegada);
fprintf(f_saida, "%d a %d: ", partida, chegada);
if(partida == chegada)
fprintf(f_saida, "(0 minutos)\n");
else
{
dist_esp = Dijkstra(G, partida, chegada, parent, dist); //EXECUTA DIJKSTRA PARA DEFINIR 'PARENT'
if(dist[chegada] == INFINITO)
fprintf(f_saida, "sem voos\n");
else
{
while (partida != chegada) //IMPRIME O CAMINHO A SER SEGUIDO
{
for(vert = chegada; vert != partida; vert = parent[vert])
filho = vert;
fprintf(f_saida, "%d-", vert);
partida = filho;
}
fprintf(f_saida, "%d ", chegada);
fprintf(f_saida, "(%d minutos)\n", dist_esp);
}
}
}
fprintf(f_saida, "\n");
fclose(f_entrada);
/** ANALISE DE TRAJETOS FECHADOS **/
fprintf(f_saida, "Trajetos fechados:\n");
vertice *expl, *comp;
expl = (vertice *)malloc(G.nvert * sizeof(vertice));
comp = (vertice *)malloc(G.nvert * sizeof(vertice));
Ciclos(G, expl, comp, f_saida); //IMPRIME OS CICLOS, SE EXISTIREM
fclose(f_saida);
return 0;
}
Scientia et Experientia
domingo, 29 de novembro de 2015
LAB 5 / CES 11
Olá! Nesta publicação, o projeto tinha a função de avaliar a manipulação de grafos, através de algoritmos como o de Dijkstra, DFS (Depth-First Search) e de Tarjan modificado para verificar a ciclicidade de um dígrafo. A ideia seria a de fornecer a uma agência aérea: os menores caminhos (custo-mínimo) e os ciclos existentes entre aeroportos. Acompanhe a seguir:
quarta-feira, 18 de novembro de 2015
LAB4 - Trabalhando com HeapSort e MergeSort
Olá! Neste laboratório, o que foi proposto é a leitura de elementos obtidos a partir de um documento de texto "entrada.txt" e, a partir dos algoritmos de ordenação HeapSort e MergeSort, ordená-los e escrever um novo arquivo "saida.txt", contendo esses elementos já ordenados e as unidades de tempo necessárias para executar essa operação por completo.
Veja, abaixo, a execução do programa e o código, por completo:
Veja, abaixo, a execução do programa e o código, por completo:
/** GUSTAVO NAHUM ALVAREZ FERREIRA **/
/** TURMA: 19.3 **/
/** LAB 4 - CES 11 **/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define teto 1000000
///FORAM USADAS DUAS STRUCTS: O NODE (UNIDADE DAS LISTAS LIGADAS)...
typedef struct node node;
struct node
{
int num;
node *prox;
};
typedef node *posicao;
///...E O NODE_HEAP (UNIDADE DO VETOR, QUE CONTERÁ O TAMANHO E O PONTEIRO PARA O INÍCIO DAS LISTAS)
typedef struct node_heap node_heap;
struct node_heap
{
int tamanho;
node *inicio;
};
typedef node_heap *heap;
//RETORNA A QUANTIDADE DE SUBSEQUENCIAS MAXIMAIS DO ARQUIVO LIDO
int quantidadeSubsequencias ()
{
//O INT NUM_ANT FOI INICIALIZADO COM "TETO", OU SEJA, 1000000...
//...POIS SE DESEJA QUE PASSE NA CONDICAO "IF" NA PRIMEIRA VEZ
int quantidade = 0, num_atual = 0, num_ant = teto;
FILE *f_entrada;
f_entrada = fopen("entrada.txt", "r");
while(fscanf(f_entrada, "%d", &num_atual) != EOF)
{
if(num_atual < num_ant)
quantidade++;
num_ant = num_atual;
}
fclose(f_entrada);
return quantidade;
}
//LE, PELA SEGUNDA VEZ, O ARQUIVO, E MONTA AS LISTAS QUE CONTEM AS SUBSEQUENCIAS
void criaHeap (heap H, int quantidade)
{
int i = 0;
node *P;
int num_ant = teto, num_atual;
FILE *f_entrada;
f_entrada = fopen("entrada.txt", "r");
i = 0;
while(fscanf(f_entrada, "%d", &num_atual) != EOF)
{
if(num_atual < num_ant)
{
//CASO "NUM_ATUAL" < "NUM_ANT", AVANCA-SE NO VETOR DE "HEAP_NODE"
//E O ESPACO "H[i].TAMANHO" EH INICIALIZADO COM 1 (POIS, AGORA, JA
//EXISTE UM PRIMEIRO "NODE" ALI)
H[++i].inicio = (node*)malloc(sizeof(node));
P = H[i].inicio;
P->num = num_atual;
P->prox = NULL;
num_ant = num_atual;
H[i].tamanho = 1;
}
else
{
//CASO CONTRARIO, AVANCA-SE NA LISTA DE UM MESMO "H[i]"
//E, LOGO, HA UM ACRESCIMO EM "H[i].TAMANHO"
P->prox = (node*)malloc(sizeof(node));
P = P->prox;
P->num = num_atual;
P->prox = NULL;
num_ant = num_atual;
H[i].tamanho++;
}
}
fclose(f_entrada);
}
///ALGORITMO "SIFT", AUXILIAR DE "HEAP-SORT"
void Sift(int i, int n, heap H)
{
int esq = 2*i;
int dir = 2*i+1;
int maior = i;
if (esq <= n && H[esq].tamanho > H[i].tamanho)
maior = esq;
if (dir <= n && H[dir].tamanho > H[maior].tamanho)
maior = dir;
if (maior != i)
{
node *aux;
int aux_int;
aux = H[i].inicio;
aux_int = H[i].tamanho;
H[i].inicio = H[maior].inicio;
H[i].tamanho = H[maior].tamanho;
H[maior].inicio = aux;
H[maior].tamanho = aux_int;
Sift(maior, n, H);
}
}
///ALGORITMO "BUILD", AUXILIAR DE "HEAP-SORT"
void Build(heap H, int quantidade)
{
int i;
for (i = quantidade/2; i > 0; i--)
Sift(i, quantidade, H);
}
///ALGORITMO "HEAP-SORT"
void HeapSort(heap H, int quantidade)
{
Build(H, quantidade);
int i;
for (i=quantidade; i>1; i--)
{
node *aux;
int aux_int;
aux = H[i].inicio;
aux_int = H[i].tamanho;
H[i].inicio = H[1].inicio;
H[i].tamanho = H[1].tamanho;
H[1].inicio = aux;
H[1].tamanho = aux_int;
Sift(1, i-1, H);
}
}
///ALGORITMO "MERGE-SORT" (ADAPTADO PARA O PROBLEMA)
int MergeSort(heap H)
{
//VAI TOMAR AS DUAS LISTAS LIGADAS INICIADAS COM "H[1].INICIO" E "H[2].INICIO"
//E, COM O AUXILIO DOS PONTEIROS "P1", "P2" E "AUX", VAI INTERCALAR OS "NODES"
//E OS SEUS "PROX" EM ORDEM CRESCENTE
posicao P1, P2, aux;
P1 = H[1].inicio;
P2 = H[2].inicio;
int tempo = H[1].tamanho + H[2].tamanho;
if(P1->num < P2->num)
{
H[1].inicio = P1;
P1 = P1->prox;
}
else
{
H[1].inicio = P2;
P2 = P2->prox;
}
while(P1->prox != NULL && P2->prox != NULL)
{
if(P1->num < P2->num)
{
if(P1->prox->num < P2->num)
P1 = P1->prox;
else
{
aux = P1->prox;
P1->prox = P2;
P1 = aux;
}
}
else
{
if(P2->prox->num < P1->num)
P2 = P2->prox;
else
{
aux = P2->prox;
P2->prox = P1;
P2 = aux;
}
}
}
if(P1->prox == NULL)
{
while(P2->prox != NULL && P2->prox->num < P1->num)
P2 = P2->prox;
if(P2->prox == NULL)
{
if(P2->num < P1->num)
P2->prox = P1;
else
P1->prox = P2;
}
else if(P2->num < P1->num)
{
aux = P2->prox;
P2->prox = P1;
P1->prox = aux;
}
else
P1->prox = P2;
}
if(P2->prox == NULL)
{
while(P1->prox != NULL && P1->prox->num < P2->num)
P1 = P1->prox;
if(P1->prox == NULL)
{
if(P1->num < P2->num)
P1->prox = P2;
else
P2->prox = P1;
}
else if(P1->num < P2->num)
{
aux = P1->prox;
P1->prox = P2;
P2->prox = aux;
}
else
P2->prox = P1;
}
return tempo;
}
int main()
{
//RESTA, NA MAIN, CHAMAR AS FUNCOES AUXILIARES E OBTER "UNIDADES_TEMPO"
int i, quantidade, unidades_tempo = 0;
node *P;
heap H;
/** PASSO I **/
quantidade = quantidadeSubsequencias();
/** PASSO II **/
H = (node_heap *) malloc ((quantidade+1) * sizeof(node_heap));
criaHeap(H, quantidade);
HeapSort(H, quantidade);
/** PASSO III **/
while(H[2].inicio != NULL)
{
//AQUI, ENFIM, OBTEM-SE AS "UNIDADES_TEMPO"
unidades_tempo += MergeSort(H);
H[1].tamanho = H[1].tamanho + H[2].tamanho;
H[2].inicio = NULL;
H[2].tamanho = teto;
HeapSort(H, quantidade);
}
/** PASSO IV **/
FILE *f_saida;
f_saida = fopen("saida.txt", "w");
for(P = H[1].inicio; P != NULL; P = P->prox)
fprintf(f_saida, "%d\n", P->num);
/** PASSO V **/
fprintf(f_saida, "%d\n", unidades_tempo);
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:
/*** 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;
}
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);
}
}
}
sexta-feira, 18 de setembro de 2015
Trabalhando com listas ligadas
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;
}
segunda-feira, 31 de agosto de 2015
Operações com matrizes de inteiros em linguagem C
Nesta primeira postagem, apresentarei meu código feito em
linguagem C, projetado para reconhecer arquivos em .txt contendo
matrizes e, em posse delas, realizar as operações: encontrar o maior
elemento, determinar a matriz transposta, realizar o produto entre duas
matrizes e, por fim, calcular o determinante de uma matriz através da
Regra de Laplace.
Com essa atividade de programação, solicitada em meu curso de Laboratório de Estruturas de Dados e Algoritmos (CES-11), pude fortalecer a minha habilidade para pensar e implementar soluções para problemas através de caminhos recursivos; além disso, foi possível recordar as aplicações de alocação dinâmica de matrizes, quebra de problemas em funções e, por fim, operações com arquivos.
Veja, a seguir, um vídeo demonstrativo da execução de meu programa:
Segue, abaixo, todo o código produzido, "LAB1.c":
Com essa atividade de programação, solicitada em meu curso de Laboratório de Estruturas de Dados e Algoritmos (CES-11), pude fortalecer a minha habilidade para pensar e implementar soluções para problemas através de caminhos recursivos; além disso, foi possível recordar as aplicações de alocação dinâmica de matrizes, quebra de problemas em funções e, por fim, operações com arquivos.
Veja, a seguir, um vídeo demonstrativo da execução de meu programa:
Segue, abaixo, todo o código produzido, "LAB1.c":
#include <stdio.h>
#include <stdlib.h>
typedef int *vetor;
typedef vetor *matriz;
int testador(matriz M, int n, int i, int j, int max){
//testa os elementos da matriz M e os compara com o maior obtido ate entao (max), retornando o maior inteiro
//n: ordem da matriz
//i e j: parametros de cada elemento da matriz (elemento M[i][j])
//percorre as linhas da esquerda para a direita:
if(i < n-1){
if(M[i][j] > max)
return testador(M, n, i+1, j, M[i][j]);
return testador(M, n, i+1, j, max);
}
//quando chega ao final de uma linha (M[i][j] = M[n-1][j]):
else if((i == n-1) && (j < n-1)){
if(M[i][j] > max)
return testador (M, n, 0, j+1, M[i][j]);
return testador (M, n, 0, j+1, max);
}
//quando chega ao final da matriz (M[i][j] = M[n-1][n-1]):
else{
if(M[i][j] > max)
return M[i][j];
else
return max;
}
}//func. testador()
int retornarMaiorElemento(matriz M, int n){
int max = M[0][0];
//os parametros i e j da func. testador comecam zerados
return testador (M, n, 0, 0, max);
}//FUNC. retornarMaiorElemento()
void DeixarMatrizPronta(matriz A, int n, int i){
//A FUNC. alocarMatriz() aloca o vetor de ponteiros, que eh apontado por **A;
//A func. DeixarMatrizPronta() alocara, entao, a matriz em si, apontada pelos ponteiros do vetor:
if (i <= n-1){
A[i] = (int *) malloc (n * sizeof (int));
DeixarMatrizPronta (A, n, i+1);
}
}//func. DeixarMatrizPronta()
matriz alocarMatriz(int n){
matriz A;
A = (vetor *) malloc (n * sizeof (vetor));
DeixarMatrizPronta (A, n, 0);
return A;
}//FUNC. alocarMatriz()
void desalocacao(matriz A, int n, int i){
//desalocara as linhas da matriz, comecando pela ultima
if (i >= 0){
free(A[i]);
desalocacao(A, n, i-1);
}
}//func. desalocacao()
void desalocarMatriz(matriz A, int n){
//desalocara o vetor de ponteiros
desalocacao (A, n, n-1);
free(A);
}//FUNC. desalocarMatriz()
void transpor (matriz M, matriz A, int n, int i, int j){
A[j][i] = M[i][j];
if (i < n-1)
i++;
else if((i == n-1) && (j < n-1)){
i = 0;
j++;
}
else if((i == n-1) && (j==n-1))
return;
transpor(M, A, n, i, j);
}//func. transpor()
matriz criarTransposta(matriz M, int n){
matriz T;
T = alocarMatriz (n);
transpor(M, T, n, 0, 0);
return T;
}//FUNC. criarTransposta()
void ZerarMatriz(matriz A, int i, int j, int n){
//func. com o objetivo de zerar a matriz A para poder receber o produto das matrizes M1 e M2
A[i][j] = 0;
if(i < n-1)
i++;
else if((i == n-1) && (j < n-1)){
i = 0;
j++;
}
else if((i == n-1) && (j == n-1))
return;
ZerarMatriz(A, i, j, n);
}//func. ZerarMatriz()
void efetuarProduto(matriz P, matriz M1, matriz M2, int i, int j, int k, int n){
//O algoritmo segue o procedimento escrito como nos somatorios:
P[i][k] += M1[i][j] * M2[j][k];
if(j < n-1)
j++;
else if((j == n-1) && (k < n-1)){
j = 0;
k++;
}
else if((j == n-1) && (k == n-1) && (i < n-1)){
j = 0;
k = 0;
i++;
}
else if((j == n-1) && (k == n-1) && (i == n-1)){
return;
}
efetuarProduto (P, M1, M2, i, j, k, n);
}//func. efetuarProduto()
matriz calcularProduto(matriz M1, matriz M2, int n){
matriz P;
P = alocarMatriz(n);
ZerarMatriz(P, 0, 0, n);
efetuarProduto(P, M1, M2, 0, 0, 0, n);
return P;
}//FUNC. calcularProduto()
void preencherMatriz(matriz X, matriz M, int j, int p, int q, int n){
//preenche X com os valores de M tirando-se a linha 0 e a coluna j (da Regra de Laplace)
if(p > 0){
if(q < j)
X[p-1][q] = M [p][q];
else if(q > j)
X[p-1][q-1] = M[p][q];
}
if(p < n-1)
preencherMatriz(X, M, j, p+1, q, n);
else if((p == n-1) && (q < n-1))
preencherMatriz(X, M, j, 0, q+1, n);
else if((p == n-1) && (q == n-1))
return;
}//func. preencherMatriz()
int calcularDeterminante (matriz M, int n){
//Regra de Laplace
if(n==1)
return M[0][0];
else{
int j, Det = 0, cofator;
matriz X;
X = alocarMatriz(n-1);
for(j=0; j <= n-1; j++){
//preencherMatriz eh a func. que torna X o Menor Complementar de A, de indices 0 e j:
preencherMatriz(X, M, j, 0, 0, n);
//O cofator eh definido pelo produto do det. do Menor Complementar (Det X) por (-1)^(0+j):
if (j%2 == 0)
cofator = calcularDeterminante(X, n-1);
else if (j%2 == 1)
cofator = (-1) * calcularDeterminante(X, n-1);
Det += M[0][j] * cofator;
}
desalocarMatriz(X, n-1);
return Det;
}
}//FUNC. calcularDeterminante()
int main(){
FILE *f1, *f2;
f1 = fopen("entrada.txt", "r");/*O arquivo "entrada.txt" sera criado pelo programa "Gerar matrizes pseudo-aleatorias.exe"*/
f2 = fopen("saida.txt", "w");
int i, j, k, Operacao, Ordem, Quantidade_de_operacoes;
fscanf(f1, "%d", &Quantidade_de_operacoes);
for(i=1; i<=Quantidade_de_operacoes; i++){
fscanf(f1, "%d", &Operacao);
fscanf(f1, "%d", &Ordem);
switch(Operacao){
case 1:{//FUNC. retornarMaiorElemento()
matriz A;
A = alocarMatriz(Ordem);
for(j=0; j< Ordem; j++)
for(k=0; k< Ordem; k++)
fscanf(f1, " %d", &A[j][k]);
fprintf(f2, "%3d\n\n",retornarMaiorElemento(A, Ordem));/*ja imprime direto o valor da FUNC.*/
desalocarMatriz(A, Ordem);
}break;
case 2:{//FUNC. criarTransposta()
matriz A, T;
A = alocarMatriz(Ordem);
for(j=0; j< Ordem; j++)
for(k=0; k< Ordem; k++)
fscanf(f1, "%d", &A[j][k]);
T = criarTransposta(A, Ordem);/*T recebe os valores de At*/
for(j=0; j < Ordem; j++){
for(k=0; k<Ordem; k++)
fprintf(f2, "%3d", T[j][k]);
fprintf(f2, "\n");
}
fprintf(f2, "\n");
desalocarMatriz(A, Ordem);
desalocarMatriz(T, Ordem);
}break;
case 3:{//FUNC. calcularProduto()
matriz A, B, P;
A = alocarMatriz(Ordem);
B = alocarMatriz(Ordem);
for(j=0; j< Ordem; j++)
for(k=0; k< Ordem; k++)
fscanf(f1, "%d", &A[j][k]);
for(j=0; j< Ordem; j++)
for(k=0; k< Ordem; k++)
fscanf(f1, "%d", &B[j][k]);
P = calcularProduto(A, B, Ordem);/*OBS: a FUNC. ja aloca espaco para P*/
for(j=0; j < Ordem; j++)
{
for(k=0; k<Ordem; k++)
fprintf(f2, "%6d", P[j][k]);
fprintf(f2, "\n");
}
fprintf(f2, "\n");
desalocarMatriz(A, Ordem);
desalocarMatriz(B, Ordem);
desalocarMatriz(P, Ordem);
}break;
case 4:{//FUNC. calcularDeterminante
matriz A;
A = alocarMatriz(Ordem);
for(j = 0; j < Ordem; j++)
for(k = 0; k < Ordem; k++)
fscanf(f1, "%d", &A[j][k]);
fprintf(f2, " %d\n\n", calcularDeterminante(A, Ordem));/*ja imprime direto o valor da FUNC.*/
desalocarMatriz(A, Ordem);
}break;
}
}
fclose(f1);
fclose(f2);
return 0;
}
Assinar:
Comentários (Atom)