segunda-feira, 30 de novembro de 2015

Atividade de Laboratório 5 - LAB EXAME

Faaaala Professor!! Deboa?? É, como o tempo passa rápido né? Final de ano chegou voando e tamo ai com o ultimo Lab de CES 11 de 2015, é nóis!! Esse lab me ensinou a manipular grafos orientados utilizando listas de adjacência, além de me ensinar a aplicação dos Algoritmos de Tarjan e Dijkstra para o mesmo digrafo. Também utilizei a ordenação de listas.

Link para o vídeo: https://youtu.be/DlBCPXbcevM

Código Fonte:
#include <bits/stdc++.h>
#define infinito 9999999

using namespace std;

///implementação da estrutura de dados descrita no arquivo do lab

typedef int vertice;
typedef struct CelAdj CelAdj;
typedef struct Dijkstra_struct Dijkstra_struct;
typedef int* vetor;
typedef vetor* matriz;

struct Dijkstra_struct
{
    int** distancia;
    int** predecessor;
};

struct CelAdj
{
    vertice vert;
    int minutos;
    CelAdj *prox;
};
struct CelVert
{
    char aeroporto[30];
    CelAdj *listaAdj;
};
struct digrafo
{
    int nvert;
    CelVert *vertices;
};
digrafo G;

void Ordenar_listas();

void Memoria()
{
    G.vertices = (CelVert*)malloc(G.nvert*sizeof(CelVert));
    for(int i = 0; i< G.nvert; i++)
    {
        G.vertices[i].listaAdj = NULL;
    }
}
void Leitura(FILE* arqEntrada)
{
    int origem, destino, lig, tempo, rotas_minimas, destino1, destino2;
    CelAdj* aux;
    fscanf(arqEntrada,"%d ", &G.nvert);
    Memoria();
    for(int i = 0; i < G.nvert ; i++)
    {
        fgets(G.vertices[i].aeroporto, 30, arqEntrada);
    }
    fscanf(arqEntrada,"%d", &lig);
    for(int j = 0; j < lig; j++)
    {
        fscanf(arqEntrada,"%d %d %d", &origem, &destino, &tempo);
        aux = G.vertices[origem].listaAdj;
        if(aux != NULL)///se já houver alguem ligado ao vertice
        {
            for(; aux->prox != NULL; aux = aux->prox);
            aux->prox = (CelAdj*)malloc(sizeof(CelAdj));
            aux = aux->prox;
            aux -> vert = destino;
            aux -> minutos = tempo;
            aux ->prox = NULL;
        }
        else///se nao houver ninguem ligado ao vertice ainda
        {
            G.vertices[origem].listaAdj = (CelAdj*)malloc(sizeof(CelAdj));
            (G.vertices[origem].listaAdj)->vert = destino;
            (G.vertices[origem].listaAdj)->minutos = tempo;
            (G.vertices[origem].listaAdj)->prox = NULL;
        }
    }
    ///ordenação das listas de adjacência; ta ok!!!
}
void Printar_Grafo(FILE* saida)
{
    fprintf(saida,"Digrafo:\n");
    for(int i = 0; i < G.nvert; i++)
    {
        fprintf(saida,"%d (%s):",i, G.vertices[i].aeroporto);
        for(CelAdj* aux = G.vertices[i].listaAdj; aux != NULL; aux = aux->prox)
        {
            if(aux->prox != NULL)
                fprintf(saida," %d(%d)", aux->vert, aux -> minutos);
            if(aux->prox == NULL)
                fprintf(saida," %d(%d)\n", aux->vert, aux -> minutos);
        }
    }
}
void Ordenar_listas()///ordena as listas de adjacência de cada elemento do vetor de structs
{
    for(int i = 0; i < G.nvert; i++)
    {
        CelAdj* aux;
        aux = G.vertices[i].listaAdj;
        if(aux->prox == NULL)
        {
            return;
        }
        else
        {
            for(; aux->prox!=NULL; aux = aux->prox)
            {
                CelAdj* q = NULL;
                q = aux->prox;
                if(q->prox == NULL)
                {
                    return;
                }
                else
                {
                    q = aux->prox;
                    q = q->prox;
                    aux = aux->prox;
                    for(; q!=NULL; q = q->prox)
                        if(q->vert < aux->vert)
                        {
                            CelAdj x = *aux;
                            *aux = *q;
                            *q = x;
                        }
                }

            }
        }
    }
}
Dijkstra_struct Dijkstra() ///Preenche as matrizes de distancia e de predecessão, aplicando o algoritmo de Dijkstra n vezes
{
    Dijkstra_struct grafo;
    CelAdj *p;
    bool **analisado;
    int n = G.nvert, menor;

    analisado = (bool**)malloc(n*sizeof(bool*));
    grafo.distancia = (matriz)malloc(n*sizeof(vetor));
    grafo.predecessor = (matriz)malloc(n*sizeof(vetor));


    for(int i = 0; i < n; i++)
    {
        grafo.distancia[i] = (vetor)malloc(n*sizeof(int));
        grafo.predecessor[i] = (vetor)malloc(n*sizeof(int));
        analisado[i] = (bool*)malloc(n*sizeof(bool));
    }

    for(int i = 0; i < n; i++)
    {
        grafo.distancia[i][i] = 0;
        grafo.predecessor[i][i] = i;
        analisado[i][i] = false;
        for(int j = 0; j < n; j++)
        {
            if(i != j)
            {
                grafo.distancia[i][j] = infinito;
                grafo.predecessor[i][j] = -1;
                analisado[i][j] = false;
            }
        }
    }

    for(int i = 0; i < n; i++)
    {
        for(int t = 0; t < n; t++)
        {
            int k;
            for(k = 0; k < n; k++)
            {
                if(!analisado[i][k])
                {
                    menor = k;
                    break;
                }
            }
            for(int j = 0; j < n; j++)
            {
                if(grafo.distancia[i][j] < grafo.distancia[i][menor] && !analisado[i][j])
                    menor = j;
            }
            analisado[i][menor] = true;
            for(p = G.vertices[menor].listaAdj; p != NULL; p = p->prox)
            {
                if(grafo.distancia[i][p->vert] > grafo.distancia[i][menor] + p->minutos)
                {
                    grafo.distancia[i][p->vert] = grafo.distancia[i][menor] + p->minutos;
                    grafo.predecessor[i][p->vert] = menor;
                }
            }
        }
    }

    return grafo;
}
void Rota_Minima(FILE* entrada, FILE* saida, Dijkstra_struct grafo, int n)
{
    stack<int> pilha;
    int rotas, de, para, atual = 0;
    fscanf(entrada, "%d", &rotas);
    fprintf(saida, "Rotas minimas:\n");
    while (rotas > 0)
    {
        fscanf(entrada, "%d %d", &de, &para);
        fprintf(saida, "%d a %d: ", de, para);
        if(grafo.distancia[de][para] < infinito)
        {

            if(para != de)
            {

                fprintf(saida, "%d", de);
                atual = para;

                while(grafo.predecessor[de][atual] != de)
                {

                    pilha.push(atual);
                    atual = grafo.predecessor[de][atual];

                }

                pilha.push(atual);

                while(!pilha.empty())
                {

                    fprintf(saida, "-%d", pilha.top());
                    pilha.pop();

                }
                fprintf(saida, " (%d minutos)\n", grafo.distancia[de][para]);

            }
            else
                fprintf(saida, "(0 minutos)\n");

        }
        else
            fprintf(saida, "sem voos\n");
            rotas--;
    }
    fprintf(saida, "\n");
}
void DFS(int* pai, int *expl, int *comp, int *ce, int *cc, int v, FILE* saida)///auxilia no algoritmo de tarjan para encontrarmos trajetos fechados
{
    CelAdj *p;
    expl[v] = ++(*ce);
    for(p = G.vertices[v].listaAdj; p != NULL; p = p->prox)
    {
        if(expl[p->vert] == 0)
        {
            pai[p->vert] = v; /// Armazenamos os pais na árvore de exploração
            DFS(pai, expl, comp, ce, cc, p->vert, saida);
        }
        else if(expl[p->vert] < expl[v] && comp[p->vert] == 0)
        {
            stack<int> pilha;
            int atual = v;
            fprintf(saida, "%d", p->vert);
            ///invertemos a ordem da impressão
            while(atual != p->vert)
            {
                pilha.push(atual);
                atual = pai[atual];
            }
            while(!pilha.empty())
            {
                fprintf(saida, "-%d", pilha.top());
                pilha.pop();
            }
            fprintf(saida, "-%d\n", p->vert);
        }
    }
    comp[v] = ++(*cc);
}
void ciclos(FILE* saida)
{
    int *pai = (vetor)malloc(G.nvert*sizeof(int));
    int *expl = (vetor)malloc(G.nvert*sizeof(int));
    int *comp = (vetor)malloc(G.nvert*sizeof(int));
    int ce = 0, cc = 0;
    for(int i = 0; i < G.nvert; i++)
    {
        expl[i] = 0;
        comp[i] = 0;
        pai[i] = -1;
    }
    fprintf(saida, "Trajetos fechados:\n");
    for(int i = 0; i < G.nvert; i++)
    {
        if(expl[i] == 0)
            DFS(pai, expl, comp, &ce, &cc, i, saida);
    }
}
int main()
{
    FILE *entrada, *saida;
    entrada = fopen("entrada.txt", "r");
    saida = fopen("saida.txt", "w");
    Leitura(entrada);
    Ordenar_listas();
    Dijkstra_struct grafo = Dijkstra();
    Printar_Grafo(saida);
    Rota_Minima(entrada, saida, grafo, G.nvert);
    ciclos(saida);
    fclose(entrada);
    fclose(saida);
}

segunda-feira, 16 de novembro de 2015

ATIVIDADE DE LABORATÓRIO 4 - ALGORITMOS DE ORDENAÇÃO

Fala prof!! Como o senhor está? Então, estamos aqui para mais um laboratório de Ces 11. Dessa vez o estudo buscou abordar a manipulação de algoritmos de ordenação O(N*logN) em listas ligadas, utilizando uma estrutura de vetor de structs, que são listas.

Segue o código fonte comentado abaixo:

Link para o Vídeo: https://youtu.be/NQANgfgGMCI


///Murilo Orofino Tarosso - T-19.3 - CES - 11

#include<stdio.h>
#include<stdlib.h>
#include <bits/stdc++.h>

using namespace std;

struct node
{
    int num;
    node * prox;
};
struct vet_structs
{
    int tamanho;
    node* pont;
};
typedef struct node node;
typedef node* posicao;
typedef node* lista;
typedef vet_structs* vetor;
typedef vetor* vetor_listas;

int Numero_Filiais(FILE* arqEntrada)
{
    int n=0, num;
    while(fscanf(arqEntrada,"%d", &num)!=EOF)
    {
        n++;
    }
    return n;
}
int Numero_Listas(FILE* arqEntrada, int n)
{
    int* v;
    v = (int*)malloc(n*sizeof(int));
    int i = 0, num, resp;
    while(fscanf(arqEntrada, "%d", &num)!= EOF)
    {
        v[i] = num;
        i++;
    }
    resp = 0;
    for(int j = 1; j <= i; j++)
    {
        if(v[j-1] > v[j])
        {
            resp++;
        }
    }
    return resp + 1;
}

node* Prox(int n)
{
    node * p = (node*)malloc(sizeof(node));
    p->num = n;
    p->prox = NULL;
    return p;
}

vet_structs* Read(int n, FILE* entrada)
{
    vetor v = (vet_structs*)malloc((n+1)*sizeof(vet_structs));
    posicao p = NULL;
    int a = 0, b = 0;
    int i = 0;
    b = INT_MAX; ///Evita análises particulares
    while(fscanf(entrada,"%d",&a) != EOF)
    {
        if(a >= b) ///mesma lista
        {
            v[i].tamanho++;
            p->prox = Prox(a);
            p = p->prox;
        }
        else ///próxima lista
        {
            i++;
            v[i].tamanho = 1;
            v[i].pont = (node*)malloc(sizeof(node));
            p = v[i].pont;
            p->num = a;
            p->prox = NULL;
        }
        b = a;
    }
    return v;
}

void Troca(vetor a, vetor b)///troca todo o conteúdo das structs a e b; troca como se fosse por igualdade de inteiros;
{
    vet_structs auxiliar = *a;
    *a = *b;
    *b = auxiliar;
}
void Sift(int i, int n, vetor v)///algoritmo Sift para a reconstrução do heap de mínimo
{
    int aux;
    int esq = 2*i;
    int dir = 2*i + 1;
    int maior = i;
    if (esq <= n && v[esq].tamanho < v[i].tamanho)
        maior = esq;
    if (dir <= n && v[dir].tamanho < v[maior].tamanho)
        maior = dir;
    if (maior != i)
    {
        aux = v[i].tamanho;
        v[i].tamanho = v[maior].tamanho;
        v[maior].tamanho = aux;
        Sift(maior, n, v);
    }
}
void Build(vetor v, int n)///Construção do Heap
{
    int i;
    for (i = n/2; i > 0; i--)
        Sift(i, n, v);
}
void Criar_Heap(vetor v, int num_listas)
{
    Build(v, num_listas);
}

vet_structs Minimo(vetor m, int n) ///Retirada da raíz, ou seja, do mínimo valor do heap
{
    vet_structs aux = m[1];
    m[1] = m[n];
    Sift(1, n-1, m);
    return aux;
}
vet_structs Merge(node* a1, node* b1, int *tempo) /// Ordenação intercalda de duas listas node dadas (a1 e b1)
{
    vet_structs A;
    A.tamanho = 1;
    A.pont = (node*)malloc(sizeof(node));
    node* p = A.pont;
    p->prox = NULL;
    if(a1->num <= b1->num) /// Evitar o armazenamento de memórias "junks"
    {
        p->num = a1->num;
        a1 = a1->prox;
    }
    else
    {
        p->num = b1->num;
        b1 = b1->prox;
    }
    (*tempo)++;
    while(a1 && b1) /// Selecionar o menor dados dois elementos para inserir na nova lista
    {
        if(a1->num <= b1->num)
        {
            p->prox = Prox(a1->num);
            a1 = a1->prox;
        }
        else
        {
            p->prox = Prox(b1->num);
            b1 = b1->prox;
        }
        p = p->prox;
        A.tamanho++;
        (*tempo)++; /// A cada número inserido, incrementamos o tempo
    }
    while(a1)
    {
        p->prox = Prox(a1->num);
        a1 = a1->prox;
        p = p->prox;
        A.tamanho++;
        (*tempo)++;
    }
    while(b1)
    {
        p->prox = Prox(b1->num);
        b1 = b1->prox;
        p = p->prox;
        A.tamanho++;
        (*tempo)++;
    }
    return A; /// Retorna a struct que entra no vetor inicial
}
int Ordenacao(vet_structs* v, int *n)
{
    int t = 0;
    if((*n) == 1) /// O processo termina quando houver apenas uma sequência
        return 0;
    vet_structs aux = Minimo(v, (*n)--); /// A passagem por referência faz-se necessária aqui
    v[1] = Merge(aux.pont, v[1].pont, &t); /// Concatenamos as duas menores listas em uma só
    return t + Ordenacao(v, n);
}
void Imprimir(vet_structs M, int t) ///Impressão da saída ordenada em um arquivo de nome "saida.txt"
{
    FILE* arqSaida = fopen("saida.txt", "w");
    for(node* p = M.pont; p != NULL; p = p->prox)
    {
        fprintf(arqSaida, "%d\n", p->num);
    }
    fprintf(arqSaida, "%d\n", t);
    fclose(arqSaida);
}

int main()
{
    FILE* arqEntrada;
    arqEntrada = fopen("entrada.txt","r");
    int m = Numero_Filiais(arqEntrada), tempo = 0;
    fclose(arqEntrada);
    arqEntrada = fopen("entrada.txt", "r");
    int n = Numero_Listas(arqEntrada, m);
    fclose(arqEntrada);
    arqEntrada = fopen("entrada.txt","r");
    vetor v = Read(n,arqEntrada);
    Criar_Heap(v, n);
    tempo = Ordenacao(v, &n);
    Imprimir(v[1], tempo);
}




terça-feira, 27 de outubro de 2015

Atividade de Laboratório 3 - 28/10/2015 - Ces 11

Fala prof Zika! Segue abaixo o código fonte e o link para o vídeo do Lab 3!Tenho breves palavras para descrever como esse lab me ajudou com manipulação de árvores que, por mais que já tenha sido cobrada em prova, ainda não tinha ficado 100% clara para mim. É com satisfação e alegria que apresento, no prazo, o código fonte do lab devidamente comentado :). Aproveito para relembrar que o curso de CES-11 foi muito importante para acrescentar muito conteúdo na minha formação acadêmica, acredito que aproveitei todas as aulas com muito apreço e extraí o máximo de informação que eu pude sobre os conteúdos desde listas, pilhas e filas, passando por árvores, algoritmos de ordenação e, por fim, grafos. Sobre o lab 3, além de me ajudar com a questão da manipulação de árvores com nós encadeados, mostrou como é possível imprimir o conteúdo de uma árvore em pré ordem utilizando recursão. Até o Lab 4 e 5!! Tamo Junto !!!


Vídeo:
Parte 1 : https://www.youtube.com/watch?v=E_NxiCRaEX4
Parte 2 : https://youtu.be/8Z5Ym8Ug_U0



Código fonte da Atividade 3:

///Murilo Orofino Tarosso
///TURMA T-19.3


#include<stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

///Declarações iniciais
struct node
{
    char letra;///a letra que vem na palavra
    int cont;/// quantas vezes já apareceu; 0 se não aparecer uma palavra da raíz até esse nó
    node* filhos[26];///NULL quando não houver filho na letra
};
typedef struct node node;
typedef node* arvore;
typedef node* posicao;

int Letra(char carac)/// Função para alocar a letra dentro de cada "casa" do vetor, retorna a posição relativa da letra em relação a letra 'a'
{
    if(carac >= 'A' && carac <= 'Z')///se a letra é maiúscula
        return carac - 'A';
    if(carac >= 'a' && carac <= 'z')///se a letra é minúscula
        return carac - 'a';
}

arvore preencher(char a)///coloca a letra em um novo node, com o contado nulo. Todos os filhos recebem NULL.
{
    arvore A = NULL;
    A = (node*)malloc(sizeof(node));///alocando o novo node arvore
    A->letra = a;///a letra de A será a
    A->cont = 0;///contador inicialmente nulo
    for(int i = 0; i < 26; i++) ///percorre todos os filhos de A, aterrando-os
    {
        A->filhos[i] = NULL;
    }
    return A;///retorna a arvore criada
}

void Ler(FILE *arqEntrada, arvore inicial)///essa função lê o arquivo de entrada construindo a arvore e a estrutura de dados requisitada
{
    posicao q = NULL;
    char aux[200];
    while(fscanf(arqEntrada,"%s", &aux) != EOF)///até identificar o fim do arquivo, EOF é #define -1
    {
        q = inicial;///Inicializa o ponteiro posicao no inicio da arvore.
        for(int i = 0; aux[i]!='\0'; i++) ///percorre cada palavra até o fim da string
        {
            if(aux[i] == '-')///se o caracter for um hífen deve-se encerrar a palavra e recomeçar uma nova palavra após o hífen
            {
                q->cont = q->cont + 1;
                q = inicial;///retornando até o início da árvore(raíz) para a construção da nova palavra.
                i++;///avança o contador pra ler a proxima palavra(pula para a proxima letra)
            }
            if(!isalpha(aux[i]))
            {
                continue;
            }
            else///se for qualquer caractere que não seja letra e nem o hífen(caso estudado abaixo) o programa deve passar pelo caractere, sem fazer nada
            {


                ///verificando se já está incializado
                if(q->filhos[Letra(aux[i])] == NULL)///se estiver aterrado(não inicializado)
                {
                    q->filhos[Letra(aux[i])] = preencher(aux[i]);///utiliza a função do preenchimento
                }
                q = q->filhos[Letra(aux[i])];///se estiver inicializados... move o ponteiro pra posição da próxima letra

            }
        }
        q->cont++;///ao finalizar essa palavra incrementa o contador dela;
    }
}

void Imprimir(FILE *arqSaida, posicao q, int i, char *palavra)///essa função imprime uma palavra especificada, é recursiva a fim de imprimir em pré ordem e ordem alfabética
{
    if(q == NULL)///posição vazia... fim da palavra ou nenhuma palavra
    {
        return;///sai da função
    }
    palavra[i] = q->letra;///vai vendo de letra em letra
    i++;///incrementa a letra
    if(q->cont != 0)/// verifica as palavras que existem e o término da palavra... se a palavra não exite ela volta ao condicional inicial
    {
        fprintf(arqSaida, "%d ", q->cont);
        for(int r = 1; r < i; r++)
        {
            fprintf(arqSaida, "%c", Letra(palavra[r])+'a');
        }
        fprintf(arqSaida,"\n");///espaço necessário entre as linhas e última linha vazia no arqSaida
    }
    for(int k = 0; k < 26; k++)
    {
        Imprimir(arqSaida, q->filhos[k], i, palavra);///recursão pra percorrer cada letra da palavra, chamando a função para a proxima node
    }
}

int main()
{
    FILE *arqEntrada, *arqSaida;
    arqEntrada = fopen("entrada.txt", "r");///já existe
    arqSaida = fopen("saida.txt", "w");///será criado
    arvore inicial = preencher('#');///char lixo padronizado no arquivo do lab enviado por email
    char palavra[100];
    Ler(arqEntrada, inicial);
    Imprimir(arqSaida, inicial, 0, palavra);///inicia a recursão em i = 0, primeiro caractere da palavra
    fclose(arqEntrada);
    fclose(arqSaida);
    return 0;
}

domingo, 4 de outubro de 2015

EXERCÍCIOS 1 E 4 - P1 DE CES11

Segue o código do Exercício 1 da P1:
O exercício tinha por objetivo o cálculo de expressões algébricas na forma simples, utilizando a estrutura de dados de árvores encadeadas diretas. A estrutura utilizada foi a de uma árvore binária, afinal, é uma árvore encadeada direta.

Código - fonte exercício 1:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

struct node
{
    float info1, info2;
    char operacao;///citar a operação : multiplicação, soma, etc.
    node *filho_esq, *filho_dir;
};
typedef node* raiz;
typedef node* arvore;

void Iniciar_Arvore(arvore a, char *exp, int *i);
raiz Formando_Arvore(char *exp);
float Calculo_Expr(raiz A);
void free_raiz(raiz A);
float CalcExpr(char *str);


raiz Formando_Arvore(char *exp)/// Recebe a expressão, contruíndo a árvore binária. Retorna um ponteiro para a sua raíz
{
    int j = 1;
    raiz A = (node*)malloc(sizeof(node));
    Iniciar_Arvore(A, exp, &j);
    return A;
}
void Iniciar_Arvore(arvore a, char *exp, int *i)
{

    if(isdigit(exp[*i]))
    {
        a->info1 = exp[*i] - '0';
        (*i)++;
        a->filho_esq = NULL;
    }
    else
    {
        a->filho_esq = (node*)malloc(sizeof(node));
        (*i)++;
        Iniciar_Arvore(a->filho_esq, exp, i);
    }
    a->operacao = exp[*i];
    (*i)++;
    if(isdigit(exp[*i]))
    {
        a->info2 = exp[*i] - '0';
        (*i)++;
        a->filho_dir = NULL;
    }
    else
    {
        a->filho_dir = (node*)malloc(sizeof(node));
        (*i)++;
        Iniciar_Arvore(a->filho_dir, exp, i);
    }
    (*i)++;
}
/// libera a arvore em pós-ordem
void free_raiz(raiz A)
{
    if(A != NULL)
    {
        free_raiz(A->filho_esq);
        free_raiz(A->filho_dir);
        free(A);
    }
}
float Calculo(char *str)
{
    raiz A = Formando_Arvore(str);
    float expr = Calculo_Expr(A);
    free_raiz(A);
    return expr;
}
float Calculo_Expr(raiz A)///Valor calculado
{
    float raiz1, raiz2;

    if(A->filho_esq != NULL)
        raiz1 =  Calculo_Expr(A->filho_esq);
    else
        raiz1 = A->info1;

    if(A->filho_dir != NULL)
        raiz2 =  Calculo_Expr(A->filho_dir);
    else
    {


        raiz2 = A->info2;

    if(A->operacao == '+')
        return raiz1 + raiz2;
    else if(A->operacao == '-')
        return raiz1 - raiz2;
    else if(A->operacao == '*')
        return raiz1 * raiz2;
    else if(A->operacao == '/')
        return raiz1 / raiz2;
    }
}
int main()
{

    char expressao[200];

    while(1)
    {
        printf("DIGITE A EXPRESSAO A SER CALCULADA (DIGITE 'OK' PARA ENCERRAR O PROGRAMA) :\n");
        scanf("%s", expressao);
        if(strcmp(expressao,"OK") == 0)
            break;
        printf("VALOR TOTAL: %f\n\n", Calculo(expressao));
    }

    return 0;
}


Código do Exercício 4 da P1:
O exercício tinha por objetivo, percorrer uma árvore binária e imprimir os nós que tem "avôs" múltiplos de 5.
Foi utilizada a estrutura de nós encadeados para árvores binárias, o que demandou o uso de recursão.

Código fonte exercício 4:

#include <stdio.h>
#include <stdlib.h>

typedef struct cell cell;
struct cell
{
    int info;
    cell *arvore_a, *filho_esq, *filho_dir;
};
typedef cell* arvore;
///Recebe um ponteiro para a raíz e printa os nós que tem avôs múltiplos de 5
void Avo_MultCinco(arvore raiz)
{
    if(raiz != NULL)
    {
        Avo_MultCinco(raiz->filho_esq);
        if((raiz->arvore_a != NULL) && (raiz->arvore_a->arvore_a != NULL) && (raiz->arvore_a->arvore_a->info)%5 == 0)
            printf("%d ", raiz->info);
        Avo_MultCinco(raiz->filho_dir);
    }
}
int main ()
{
    ///lê uma árvore
    return 0;
}



 

terça-feira, 15 de setembro de 2015

ATIVIDADE DE LABORATÓRIO 2 - DICIONÁRIO ITEANO

https://www.youtube.com/watch?v=JuTiypw0_ks&feature=youtu.be Dando continuidade as atividades laboratoriais da disciplina de ces-11 do Prof. Yano, segue o código fonte da atividade 2, o dicionário iteano. Com essa atividade foi possível um primeiro contato com estruturas de dados em geral, em particular com as tabelas de dispersão(hash-tables), além de relembrar conceitos importantes de lista ligada e alocação dinâmica. Vale lembrar que foi imporatnte devido ao alto uso de ponteiros.

Link para o vídeo : https://www.youtube.com/watch?v=JuTiypw0_ks&feature=youtu.be

Segue o código fonte:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


typedef struct nodeSignificado nodeSignificado;
typedef struct nodeExpressao nodeExpressao;

struct nodeSignificado
{
    char signif[50];
    nodeSignificado *prox;
};
struct nodeExpressao
{
    char expr[50];
    nodeSignificado *listaSignificado;
    nodeExpressao *prox;
};///declarações
typedef struct nodeExpressao *vetor;
typedef vetor *vetor_ponteiros;

void EliminarExpressao(vetor_ponteiros L, char *expr, int N);
void InserirSignificado(vetor_ponteiros L, int N, char *expr, char *sign);
void Ler_Linha(char *linha, char *expr, char *sign);
vetor_ponteiros CarregarDados(FILE *arqEntrada, int N);
void ConsultarExpressao(char *expr, vetor_ponteiros L, int N, FILE *arqSaida);
void InserirSignificado(vetor_ponteiros L, char *expr, char *novo_signif, int N);
void ElimiarSignificado(vetor_ponteiros L, char* expr, char *signif, int N);
void EliminarExpressao(vetor_ponteiros L, char *expr, int N);
void GerarBaseDados(vetor_ponteiros L, int N, FILE *arqSaida);




void InserirSignificado(vetor_ponteiros L, int N, char *expr, char *sign)
{
    int hash = 0;
    for(int i = 0; expr[i] !='\0'; i++)
    {
        hash += expr[i];
    }
    hash = hash % N;

    vetor p = L[hash];
    if(p == NULL)  ///hash vazio
    {
        L[hash] = (nodeExpressao*)malloc(sizeof(nodeExpressao));
        p = L[hash];
        p->prox = NULL;
        strcpy(p->expr, expr);
        p->listaSignificado = (nodeSignificado*)malloc(sizeof(nodeSignificado));
        strcpy(p->listaSignificado->signif, sign);
        p->listaSignificado->prox = NULL;
    }
    else  ///hash já ocupado
    {
        vetor aux = p;
        bool state = true;

        while(p != NULL && state)
        {
            if(strcmp(p->expr, expr))
            {
                aux = p;
                p = p->prox;
            }
            else
                state = false;
        }

        if(p == NULL)  ///Não existe a expressão
        {
            aux->prox = (nodeExpressao*)malloc(sizeof(nodeExpressao));
            p = aux->prox;
            p->prox = NULL;
            p->listaSignificado = (nodeSignificado*)malloc(sizeof(nodeSignificado));
            strcpy(p->listaSignificado->signif, sign);
            p->listaSignificado->prox = NULL;
        }
        else  ///Já existe a expressão
        {
            nodeSignificado *q = p->listaSignificado, *r;
            bool state = true;

            while(q != NULL && state)
            {
                if(strcmp(q->signif, sign))
                {
                    r = q;
                    q = q->prox;
                }
                else
                    state = false;
            }

            if(q == NULL)  ///significado ainda não existe
            {
                r->prox = (nodeSignificado*)malloc(sizeof(nodeSignificado));
                r = r->prox;
                r->prox = NULL;
                strcpy(r->signif, sign);
            }
        }
    }
}
void Ler_Linha(char *linha, char *expr, char *sign)
{
    char *pch;
    linha[strlen(linha) - 1] = '\0';
    pch = strtok(linha,"|");
    strcpy(expr, pch);
    pch = strtok(NULL,"|");
    strcpy(sign,pch);
}
vetor_ponteiros CarregarDados(FILE *arqEntrada, int N)
{
    vetor_ponteiros L = new vetor[N];
    char linha[100];
    for(int i = 0; i < N; i++)
        L[i] = NULL;

    while(fgets(linha, 100, arqEntrada) != NULL)
    {
        char expr[50], sign[50];
        Ler_Linha(linha, expr, sign);
        InserirSignificado(L, N, expr, sign);
    }

    return L;
}

void ConsultarExpressao(char *expr, vetor_ponteiros L, int N, FILE *arqSaida)///função numero 2
{
    int hash = 0;
    for(int i = 0; expr[i] != '\0'; i++)
    {
        hash += expr[i];
    }
    hash = hash % N;
    vetor p = L[hash];
    if(p)
    {
        bool state = true;
        while(p && state)
        {
            if(strcmp(p->expr, expr))
            {
                p = p->prox;
            }
            else
                state = false;
        }
        if(!state)
        {
            nodeSignificado *q = p->listaSignificado;
            while(q)
            {
                fprintf(arqSaida, "%s\n", q->signif);
                q = q->prox;
            }
            fprintf(arqSaida, "\n");
        }
        else
        {
            fprintf(arqSaida,"nada consta\n");
        }
    }
    else
        fprintf(arqSaida,"nada consta\n");
}
void InserirSignificado(vetor_ponteiros L, char *expr, char *novo_signif, int N)///função numero 3
{
    int hash = 0;
    for(int i = 0; expr[i] != '\0'; i++)
    {
        hash += expr[i];
    }
    hash = hash % N;

    vetor p = L[hash];
    if(p == NULL)  ///hash vazia
    {
        L[hash] = (nodeExpressao*)malloc(sizeof(nodeExpressao));
        p = L[hash];
        p->prox = NULL;
        strcpy(p->expr, expr);
        p->listaSignificado = (nodeSignificado*)malloc(sizeof(nodeSignificado));
        strcpy(p->listaSignificado->signif, novo_signif);
        p->listaSignificado->prox = NULL;
    }
    else  ///Colisão ou significado existe
    {
        vetor aux = p;
        bool estado = true;

        while(p != NULL && estado)
        {
            if(strcmp(p->expr, expr))
            {
                aux = p;
                p = p->prox;
            }
            else
                estado = false;
        }

        if(p == NULL)  ///Ainda não existe expressão
        {
            aux->prox = (nodeExpressao*)malloc(sizeof(nodeExpressao));
            p = aux->prox;
            p->prox = NULL;
            p->listaSignificado = (nodeSignificado*)malloc(sizeof(nodeSignificado));
            strcpy(p->listaSignificado->signif, novo_signif);
            p->listaSignificado->prox = NULL;
        }
        else  ///Expressão já existente
        {
            nodeSignificado *q = p->listaSignificado, *r;
            bool estado = true;

            while(q != NULL && estado)
            {
                if(strcmp(q->signif, novo_signif))
                {
                    r = q;
                    q = q->prox;
                }
                else
                    estado = false;
            }

            if(q == NULL)  /// Significado não existe
            {
                r->prox = (nodeSignificado*)malloc(sizeof(nodeSignificado));
                r = r->prox;
                r->prox = NULL;
                strcpy(r->signif, novo_signif);
            }
        }
    }
}

void ElimiarSignificado(vetor_ponteiros L, char* expr, char *signif, int N)///função numero 4
{
    int hash = 0;

    for(int i = 0; expr[i] !='\0'; i++)
        hash += expr[i];
    hash = hash % N;
    vetor p = L[hash];
    bool estado = true;

    while(p && estado)
    {
        if(strcmp(p->expr, expr))
        {
            p = p->prox;
        }
        else
            estado = false;
    }

    if(!estado)  /// Expressão existe
    {
        nodeSignificado *r = p->listaSignificado, *s = NULL;
        bool estado = true;

        while(r && estado)
        {
            if(strcmp(r->signif, signif))
            {
                s = r;
                r = r->prox;
            }
            else
                estado = false;
        }

        if(!estado)  ///significado a ser eliminado
        {
            if(!s)  /// Primeiro significado da listaSignificado
            {
                if(!(r->prox)) ///Um significado
                    EliminarExpressao(L, expr, N);
                else
                {
                    p->listaSignificado = r->prox;
                    free(r);
                }
            }
            else
            {
                s->prox = r->prox;
                free(r);
            }
        }
    }
}

void EliminarExpressao(vetor_ponteiros L, char *expr, int N)///função numero 5
{
    int hash = 0;
    for(int i = 0; expr[i] !='\0'; i++)
        hash += expr[i];
    hash = hash % N;

    vetor p = L[hash], q = NULL;
    bool estado = true;
    while(p && estado)
    {
        if(strcmp(p->expr, expr))
        {
            q = p;
            p = p->prox;
        }
        else
            estado = false;
    }

    if(!estado)
    {
        nodeSignificado *r = p->listaSignificado, *s;
        while(r)
        {
            s = r;
            r = r->prox;
            free(s);
        }

        if(q)  /// Não é a primeira expressão da lista
        {
            q->prox = p->prox;
        }
        else  /// É a primeira da lista de expressões
        {
            L[hash] = p->prox;
        }

        free(p);
    }
}

void GerarBaseDados(vetor_ponteiros L, int N, FILE *arqSaida)///função numero 6
{
    int i = 0;
    vetor p, q;
    for(i = 0; i < N; i++)
    {
        p = L[i];
        while(p)
        {
            nodeSignificado *r = p->listaSignificado, *s;
            while(r)
            {
                fprintf(arqSaida, "%s|%s\n", p->expr, r->signif);
                s = r;
                r = r->prox;
                free(s);
            }
            q = p;
            p = p->prox;
            free(q);
        }
    }
    free(L);
}
int main ()
{

    FILE *arqEntrada1,*arqEntrada2, *teste, *arqSaida;
    vetor_ponteiros L;
    int N, n_operacoes, codigo = 0;
    char expr[50], signif[50], lixo,aux[200];
    char *pch;
    arqEntrada1 = fopen("entrada.txt","r");
    arqEntrada2 = fopen("DicionITA.txt", "r");
    arqSaida = fopen("saida.txt","w");
    fscanf(arqEntrada1,"%d",&N);
    fscanf(arqEntrada1,"%d",&n_operacoes);
    while(n_operacoes > 0)
    {
        fscanf(arqEntrada1,"%d%c", &codigo,&lixo);
        switch(codigo)
        {
        case 1:
            L = CarregarDados(arqEntrada2, N);
            fclose(arqEntrada2);
            teste = fopen("DicionITA.txt","w");
            break;
        case 2:
            fscanf(arqEntrada1,"%s", expr);
            ConsultarExpressao(expr,L, N, arqSaida);
            break;
        case 3:
            fgets(aux,101,arqEntrada1);
            aux[strlen(aux)-1]='\0';
            pch = strtok(aux,"|");
            strcpy(expr,pch);
            pch = strtok(NULL,"|");
            strcpy(signif,pch);
            InserirSignificado(L, expr, signif, N);
            break;
        case 4:
            fgets(aux,101,arqEntrada1);
            aux[strlen(aux)-1]='\0';
            pch = strtok(aux,"|");
            strcpy(expr,pch);
            pch = strtok(NULL,"|");
            strcpy(signif,pch);
            ElimiarSignificado(L, expr, signif, N);
            break;
        case 5:
            fscanf(arqEntrada1, "%s", expr);
            EliminarExpressao(L, expr, N);
            break;
        case 6:
            GerarBaseDados(L, N, teste);
            break;
        }
        n_operacoes--;
    }
    fclose(arqEntrada1);
    fclose(teste);
    fclose(arqSaida);

    return 0;
}

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;
}