A prática de Laboratório 1, incentivou a capacidade de criação e implementação recursiva, dando uma maior noção de como construir funções recursivas e otimizar programas e códigos, reduzindo seu tempo de execução. Além de relembrar conceitos importantes de CES - 10, como a alocação dinâmica de matrizes, passagem por referência e o conceito de ponteiros, ou apontadores.
Aluno : Murilo Orofino Tarosso
Código fonte:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
typedef int *vetor;
typedef vetor *matriz;
void desalocarMemoria(matriz A, int n);
matriz AlocarMatriz(int n);
void LerMatriz(int n);
matriz MenorComplementar(matriz A, int n, int linha, int coluna);
void desalocarMemoria(matriz A,int n);
int calcularDeterminante(matriz A, int n);
int retornarMaiorElemento(matriz M, int n);
void imprimirMatriz(matriz M, int n);
matriz calcularProduto(matriz M1, matriz M2, int n);
matriz criarTransposta(matriz M, int n);
void calcularProduto_rec(matriz M1, matriz M2, int n, int i, int j, int k, matriz resultado);
void criarTransposta_recursiva(matriz M, int n, int a, int b, matriz resp);
matriz AlocarMatriz(int n)///Alocçãode memória referente a matriz de ordem n, inicializando-a com 0 em todos os elementos.
{
matriz aux;
aux = (matriz)malloc(n*sizeof(vetor));
for(int i = 0; i < n; i++)
{
aux[i] = (vetor)malloc(n*sizeof(int));
}
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
aux[i][j] = 0;
}
}///incialização dos elementos como zero.
return aux;
}
void LerMatriz(matriz M, int n, FILE *arqEntrada)///lê a matriz de ordem n, do arquivo entrada.txt
{
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
fscanf(arqEntrada,"%d", &M[i][j]);
}
}
}
matriz MenorComplementar (matriz A, int n, int linha, int coluna)
{
matriz m;
m=(matriz)malloc((n-1)*sizeof(vetor));
for(int i=0; i<n-1; i++)
{
m[i]=(vetor)malloc((n-1)*sizeof(int));
}
if (coluna == 0)///caso particular da criacao dos cofatores
{
for(int i = 1; i < n; i++)
{
for(int j = 1; j < n; j++)
{
m[i-1][j-1] = A[i][j];
}
}
}
else
{
for(int i = 1; i < n; i++)///alocando os valores que estao na coluna atras da escolhida
{
for(int j = 0; j < coluna; j++)
{
m[i-1][j]=A[i][j];
}
}
for(int i = 1; i < n; i++)///alocando os valores que estao apos a coluna escolhida
{
for(int j = coluna + 1; j < n; j++)
{
m[i-1][j-1]=A[i][j];
}
}
}
return m;
desalocarMemoria(m,n-1);
}
int calcularDeterminante(matriz A, int n)
{
int multiplicador;
int resp = 0;
if(n == 1)///caso trivial
resp = A[0][0];
if(n == 2) ///caso trivial
{
return (A[0][0]*A[1][1])- (A[0][1]*A[1][0]);
}
if(n == 3)///caso trivial; Visando otimizar a recursão do exercicio;
resp = A[0][0]* A[1][1]* A[2][2]+ A[0][1]* A[1][2]* A[2][0]+A[0][2]* A[1][0]* A[2][1]- A[0][1]* A[1][0]* A[2][2]-A[0][0]* A[1][2]* A[2][1]- A[0][2]* A[1][1]* A[2][0];
else
{
for(int i = 0; i < n; i++)
{
multiplicador = (int)pow(-1, i);
resp += calcularDeterminante(MenorComplementar(A, n,0,i),n-1)*multiplicador*A[0][i];///Laplace. Menor complementar retorna uma matriz.
}
}
return resp;
}
void desalocarMemoria(matriz A,int n)///desaloca a memória referente a matriz M, de ordem n.
{
for(int i = 0; i < n; i++)///free nos ponteiros.
{
free(A[i]);
}
free(A);
}
int compararNumVetor(vetor v, int dim)/// compara os elementos de um vetor e identifica o maior deles, recursivamente
{
if(dim == 1)
{
return v[0];
}
if(dim == 2)
{
if(v[1] > v[0])
return v[1];
else return v[0];
}
else
{
if(v[dim-1] > compararNumVetor(v,dim-1))
return v[dim-1];
else return compararNumVetor(v,dim-1);
}
}
int retornaMaiorElemento(matriz M, int coluna)///compara os elementos de uma matriz e identifica o maior deles, recursivamente
{
if(coluna == 1)
{
return M[0][0];
}
else if(coluna == 2)
{
if(compararNumVetor(M[1],coluna) > compararNumVetor(M[0],coluna))
{
return compararNumVetor(M[1],coluna);
}
else return compararNumVetor(M[0],coluna);
}
else
{
if(compararNumVetor(M[coluna - 1],coluna) > retornaMaiorElemento(M,coluna-1))
{
return compararNumVetor(M[coluna-1],coluna);
}
else return retornaMaiorElemento(M,coluna-1);
}
}
void escreverMatriz(matriz M, int n, FILE *arqSaida)/// imprime uma matriz de ordem n em um arquivo de saida
{
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
fprintf(arqSaida,"%d ", M[i][j]);
}
fprintf(arqSaida,"\n");
}
fprintf(arqSaida,"\n");
}
void calcularProduto_rec(matriz M1, matriz M2, int n, int i, int j, int k, matriz resultado)///função auxiliar para o cálculo do produto
{
if(i < n)
{
if(j < n)
{
if(k < n)
{
resultado[i][j] += M1[i][k] * M2[k][j];
calcularProduto_rec(M1,M2,n,i,j,k+1,resultado);
}
else calcularProduto_rec(M1,M2,n,i,j+1,0,resultado);
}
else calcularProduto_rec(M1,M2,n,i+1,0,0,resultado);
}
}
matriz calcularProduto(matriz M1, matriz M2, int n)///função utilizada na main para o cálculo do produto de M1 por M2, nessa ordem.
{
matriz resultado;
resultado = AlocarMatriz(n);
calcularProduto_rec(M1,M2,n,0,0,0,resultado);
return resultado;
}
void criarTransposta_recursiva(matriz M, int n, int a, int b, matriz resp)///função auxiliar utilizada no cálculo da transposta de uma matriz
{
int aux = 0;
if(a < n)
{
if(b < n)
{
aux = M[b][a];
resp[a][b] = aux;
criarTransposta_recursiva(M,n,a,b+1,resp);
}
criarTransposta_recursiva(M,n,a+1,0,resp);
}
}
matriz criarTransposta(matriz M, int n)///função utilizada na main para o cálculo da matriz transposta, recursivamente.
{
matriz resp;
resp = AlocarMatriz(n);
criarTransposta_recursiva(M,n,0,0,resp);
return resp;
}
int main ()
{
FILE *arqEntrada, *arqSaida;
char lixo[1];
int nop, op, n, maior, determinante;
matriz M, M2, M_transposta, M_produto;
arqEntrada = fopen("entrada.txt","r");
arqSaida = fopen("saida.txt","w");
fscanf(arqEntrada,"%d",&nop);///quantidade de operações a serem realizadas.
for(int i =0; i < nop; i++)
{
fscanf(arqEntrada,"%d", &op);///indica qual operação será relizada
fscanf(arqEntrada,"%d",&n);///indica a ordem da matriz.
switch(op)
{
case 1:///maior elemento
M = AlocarMatriz(n);
LerMatriz(M,n,arqEntrada);
maior = retornaMaiorElemento(M,n);
fprintf(arqSaida,"MAIOR ELEMENTO: %d\n\n", maior);
desalocarMemoria(M,n);
break;
case 2:///transposta
M = AlocarMatriz(n);
LerMatriz(M,n,arqEntrada);
M_transposta = criarTransposta(M,n);
escreverMatriz(M_transposta,n,arqSaida);
desalocarMemoria(M,n);
desalocarMemoria(M_transposta,n);
break;
case 3:///produto entre matrizes
M = AlocarMatriz(n);
M2 = AlocarMatriz(n);
LerMatriz(M,n,arqEntrada);
LerMatriz(M2,n,arqEntrada);
M_produto = calcularProduto(M,M2,n);
escreverMatriz(M_produto, n,arqSaida);
desalocarMemoria(M, n);
desalocarMemoria(M2, n);
desalocarMemoria(M_produto, n);
break;
case 4:///determinante
M = AlocarMatriz(n);
LerMatriz(M, n,arqEntrada);
determinante = calcularDeterminante(M, n);
fprintf(arqSaida,"DETERMINANTE: %d\n", determinante);
desalocarMemoria(M, n);
break;
default:
fprintf(arqSaida,"OPERAÇÃO INVALIDA\n");
break;
}
fgets(lixo,1,arqEntrada);///tira a linha vazia do arquivo de entrada
}
return 0;
}
Nenhum comentário:
Postar um comentário