domingo, 30 de agosto de 2015

Atividade de Laboratório 1



Como requisitado pelo Prof. Yano, seguem os links do vídeo e do código fonte da primeira atividade prática do curso de CES-11 do 2º semestre do 1º ano do Instituto Tecnológico de Aeronáutica - ITA.
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

Turma 19.3
H8C- 327/A
@murilo.tarosso
murilotarosso@gmail.com

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