/* Programa que implementa o Tipo Abstrato de Dados Pilha com alocacao dinamica * Objetivo: organizar recibos em uma estrutura de dados que ilustra o funcionamento real de uma pilha de recibos real * Restricoes: a pilha consiste em elementos recibos, pois estah adaptado para este programa * Observacoes: o tipo bool estah definido em utils.h e consiste em um int para representar valores booleanos * * Autores: Bruno Freitas Tissei e Felipe Shi Iu Wu * Disciplina: Algoritmos e Estrutura de Dados II * Entrega: 20/11/2015 */ #include "pilha.h" // inicia a pilha void inicPilha(tipoPilha *pilha, int logbool) { if (logbool) imprimeLog("Iniciei a Pilha usando alocacao dinamica"); pilha->tamanho = 0; pilha->topo = (recibo*) malloc(sizeof(recibo)); pilha->topo->frente = NULL; } // verifica se a pilha estah vazia (vazia -> true) bool vaziaPilha(tipoPilha pilha) { return !pilha.tamanho; } // retorna o tamanho da pilha int tamanhoPilha(tipoPilha pilha) { return pilha.tamanho; } // adiciona um elemento recibo ao topo, eh necessario fornecer o nome e o valor gasto que irao no recibo // parametro logbool informa se eh necessario imprimir a operacao no log ou nao, pois // a funcao push eh chamada dentro do inverte pilha void push(tipoPilha *pilha, char *nome, float valorGasto, bool logbool) { if (logbool) { sprintf(straux, "Empilhei o elemento recibo = (%s, %.2f)", nome, valorGasto); imprimeLog(straux); } recibo *aux; aux = (recibo*) malloc(sizeof(recibo)); aux->frente = pilha->topo; strcpy(pilha->topo->nome, nome); pilha->topo->valorGasto = valorGasto; pilha->topo = aux; pilha->tamanho++; } // se nao estiver vazia remove o recibo do topo da pilha e o retorna // parametro logbool informa se eh necessario imprimir a operacao no log ou nao, pois // a funcao pop eh chamada dentro do inverte pilha recibo pop(tipoPilha *pilha, bool logbool) { recibo *aux; if (vaziaPilha(*pilha)) { if (logbool) imprimeLog("ERRO: impossivel desempilhar, Pilha Vazia!"); printf("Pilha vazia.\n"); } else { aux = pilha->topo; pilha->topo = aux->frente; free(aux); pilha->tamanho--; if (logbool) { sprintf(straux, "Desempilhei o elemento recibo = (%s, %.2f)", pilha->topo->nome, pilha->topo->valorGasto); imprimeLog(straux); } return *(pilha->topo); } } // imprime a pilha // parametro logbool informa a forma correta de imprimir a operacao no log, pois // a funcao imprimePilha eh chamada dentro do inverte pilha void imprimePilha(tipoPilha pilha, int logbool) { recibo *aux; if (vaziaPilha(pilha)) { if (logbool) imprimeLog("Veja a Pilha: [ ]"); else imprimeLog("Veja a Pilha Invertida: [ ]"); printf("Pilha vazia.\n"); } else { aux = pilha.topo->frente; if (logbool) imprimeLog("Veja a Pilha: ["); else imprimeLog("Veja a Pilha Invertida: ["); while (aux != NULL) { sprintf(straux, "\t(%s, %.2f)", aux->nome, aux->valorGasto); imprimeLog(straux); printf("Nome: %s | Gasto total: R$%.2f\n", aux->nome, aux->valorGasto); aux = aux->frente; } imprimeLog("]"); } } // inverte a pilha e imprime a invertida // a inversao eh feita com uma pilha auxiliar void invertePilha(tipoPilha *pilha) { imprimeLog("Inverti a Pilha"); tipoPilha auxPilha; recibo *aux = pilha->topo->frente; inicPilha(&auxPilha, 0); while (aux != NULL) { push(&auxPilha, aux->nome, aux->valorGasto, 0); pop(pilha, 0); aux = aux->frente; } pilha->topo->frente = auxPilha.topo->frente; pilha->tamanho = auxPilha.tamanho; free(auxPilha.topo); imprimePilha(*pilha, 0); }