/*! * \file sortui.c * \brief Módulo da interface com usuário. * * \date 02-05-2012 16:36:35 * \version 0.0.1 * \author Alessandro Elias, ae11@inf.ufpr.br * \author Ruanito Diego Santos, rds@inf.ufpr.br * * \details Este módulo possui todas as funcões que * interagem com o usuário, o TUI (text user interface). */ #include #include #include #include #include /* para strcasecmp() */ #include /* Chamada a funcao do sistema para verificar se STDIN tem dados no buffer. */ #include /* para read() e poll()*/ #include #include /* para setupterm() */ #include /* tigetnum() */ #include #include "mydebug.h" #include "sortui.h" #include "log.h" #include "buscaseq.h" #include "buscabinaria.h" #include "selectsort.h" #if defined(INCLUDE_QUICK_SORT) #include "quicksort.h" #endif /*! * Variável blobal, recebe valor da função isatty(). * \details isatty() retorna 1 quando file descriptor * esta conectado a um terminal, 0 caso * contrário. */ bool g_bStdinConnectedTotty; /*! Variável global, armazena número de colunas do terminal do usuário. */ int g_ncols = DEFAULT_COLS; /*! Variável global, armazena número de linhas do terminal do usuário. */ int g_nlines = DEFAULT_LINES; /*! Não implementado. Daria opção ao usuário * de pressionar 'q' e não limpar a tela, * enter limparia o terminal. */ bool g_bCleanSrc = TRUE; /*! Vetor com os elementos desordenados. \sa SIZE_OF_ARRAY */ static int g_ArrayUnsorted[SIZE_OF_ARRAY]; /*! Vetor com os elementos ordenados. \sa SIZE_OF_ARRAY */ static int g_ArraySorted[SIZE_OF_ARRAY] = {0}; /*! True o vetor g_ArraySorted esta ordenado, False caso contrário. */ static bool g_bArraySorted = FALSE; /*! Vetor com números de comparações feitas * em 1000 casos da busca sequencial, utilizado * para calcular a variância. */ static int g_nSeqComp[MAX_AVERAGE]; /*! Vetor com números de comparações feitas * em 1000 casos da busca binária, utilizado * para calcular a variância. * \sa MAX_AVERAGE */ static int g_nBinComp[MAX_AVERAGE]; /*! Vetor com números de comparações feitas * em 1000 casos da ordenação pelo select_sort, * utilizado para calcular a variância. * \sa MAX_AVERAGE */ static int g_nSelComp[MAX_AVERAGE]; #if defined(INCLUDE_QUICK_SORT) /*! Vetor com números de comparações feitas * em 1000 casos da ordenação pelo quick_sort, * utilizado para calcular a variância. * \sa MAX_AVERAGE */ static int g_nQkComp[MAX_AVERAGE]; #endif /* __________________________________________________________________________________ */ /*! * Ponto de inicialização do program. * * \return 0 em caso o programa foi executado com sucesso, caso contrário * código do erro ocorrido. * * \sa GenerateRndArray, read_input, Greeting, PrintMenu, MoreInput, * OpenLog, CloseLog, LogMessage, WaitReturn, ParseOption */ int main(void) { char szOpt[4]; /* input of user, maximum 3 chars. */ enum eOptMenu opt; /* option from the menu. */ OpenLog(); if( !setupterm(NULL, fileno(stdout), (int*)NULL) ) /* setup terminal that user is using. */ { /* Get size of screen from user. */ g_ncols = tigetnum("cols"); g_nlines = tigetnum("lines"); if( g_ncols == 0 ) g_ncols = DEFAULT_COLS; if( g_nlines == 0 ) g_nlines = DEFAULT_LINES; } /* * Obtenha valor booleano se usuario redirecionou stdin. * (Ver descricao na secao global) */ g_bStdinConnectedTotty = isatty(STDIN_FILENO); GenerateRndArray(g_ArrayUnsorted, SIZE_OF_ARRAY); Greeting(); PrintMenu(); read_input(szOpt, sizeof(szOpt)); /* * atoi() se encaregara de nos retornar o inteiro. * Em caso usuario entrou algo arbitrario do que um * inteiro in ascii, atoi retornara 0, o que não e * identificado em ParseMenu(). */ opt = (enum eOptMenu)atoi(szOpt); while( opt != oExit ) { /* Se usuario ja entrou um comando, entao processe ele ate que não haja mais comandos. */ while( (opt = ParseOption(szOpt, opt)) != oNone ) ; Greeting(); PrintMenu(); read_input(szOpt, sizeof(szOpt)); opt = (enum eOptMenu)atoi(szOpt); }/* while */ LogMessage("%d selecionada.\n", opt); /* feche streams */ CloseLog(); return EXIT_SUCCESS; }/* main */ /*! Le dados da entrada padrão. * * \param [out] pbuff - ponteiro que receberá o buffer * com dados entrado pelo usuário. * \param [in] size - número de caracteres que deve ser * lido da entrada padrão, incluindo null. * * \return Número de caracteres lidos da entrada padrão, * exceto null. */ int read_input(char *pbuff, int size) { char *p; int n, err; memset(pbuff, '\0', size); n = read(STDIN_FILENO, pbuff, size-1); err = errno; if( n == -1 ) { PERRLN("Erro 'read_input' falhou"); LogMessage("Erro 'read_input' falhou: %s.\n", strerror(err)); *pbuff = '\0'; WaitReturn(); return 0; } /* garantee null terminated. */ if( (p = strchr(pbuff, '\n')) != NULL ) { *p = '\0'; n--; } else *(pbuff+size) = '\0'; /* * Verifique se usuario entrou mais dados que * o limite do buffer, se sim consuma o restante. * Isto deve ocorrer soment se stdin estiver connectado * a um terminal. */ if( g_bStdinConnectedTotty && MoreInput() ) { fprintf(stderr, "ATENÇÃO! Char's execendes de '%s' foram truncados.\n", pbuff); LogMessage("ATENÇÃO! Char's execendes de '%s' foram truncados.\n", pbuff); WaitReturn(); /* WaitReturn ja ira esvaziar buffer. */ } return n; }/* read_input */ /*! * função verifica se há mais dados a serem lidos da * entrada padrão. * * \return True há mais dados a serem lidos da entrada padrão, * False caos contrário. * * \remarks Esta decisão de implementação fez-se * necessária, uma vez que decidimos que o usuário * é livre para dar entrada ao programa sem * filtrar o que o usuário entrou. O comportamento * de read() em caso a entrada do usuário é maior que * o buffer passado a ela, é de: na subsequente chamada * a ela, irá retornar o restante da entrada do usuário, * até que possa ser lido toda entrada do usuário, uma vez * todo o buffer foi consumido, subsequente chamada irá entrar * em modo de espera até que seja dada uma outra entrada, em outras * palavras, quando tem mais dados no buffer do stdin, as chamadas * ao read() retornara imediatamente, até que não reste mais nada no * stdin. */ bool MoreInput(void) { struct pollfd fds; /* estrutura com os dados a chamada do sistema low-level */ fds.fd = STDIN_FILENO; /* fileno(stdin) retorna zero, afinal 0 e o descriptor da entrada padrao. */ fds.events = POLLIN; /* evento que estamos interessado, neste caso se ha dados em stdin. */ fds.revents = 0; /* Nao estamos interesados em eventos de retorno. */ /* * poll() retorna o numero de fds que tem * o status de interesse, caso nao haja dados em stdin * poll retorna 1 (neste caso, temos somente um fd), 0 * caso contrario. */ return( poll(&fds, 1, 0) == 1 ); }/* MoreInput */ /*! * \brief Consome dados da entrada padrão. * Isto fará com que os dados a mais * que o usuário entrou sejam ignorados. * A leitura byte a byte faz-se necessária, pois o programa * pode estar trabalhando com um arquivo de entrada, assim * podemos identificar cada final de entrada com LF '\n'. * * \remarks Note que esta função só é útil quando o programa esta interagindo * com o usuário. Nesta condição podemos fazer o programa ignorar a * entrada que excede algum buffer. */ void EmptyStdIn(void) { char ch = 0; /* nao faca nada com os dados lidos, apenas ignore-os * ate que seja encontrado LF ('\n'). */ while( ch != '\n' && read(STDIN_FILENO, &ch, 1) > 0 ) ; }/* EmptyStdIn */ /*! * Imprime título do programa. */ void Greeting(void) { /* * When a */ static const char *szTitle[] = { "Métodos de Pesquiza", "e Ordenação v 0.0.1" }; char buff[256]; int x, nl1, nl2; int centerl1, centerl2; #undef TOTAL #define TOTAL 48 /* verifique se usuário deseja limpar o terminal. */ if( g_bCleanSrc ) { system("clear"); g_bCleanSrc = TRUE; } memset(buff, '-', 254); buff[255] = '\0'; /* calcule centro da tela */ nl1 = strlen(szTitle[0]); /* Tamanho da linha 1 do titulo */ nl2 = strlen(szTitle[1]); /* Tamanho da linha 2 do titulo */ centerl1 = (TOTAL - nl1) / 2; /* centralize linha 1 no meio de +---...---+ */ centerl2 = (TOTAL - nl2) / 2; /* centralize linha 2 no meio de +---...---+ */ x = (g_ncols - 48) / 2; /* obtenha centro da tela */ puts("\n"); printf("%*s+%*.*s+\n", x, " ", TOTAL, TOTAL, buff); printf("%*s|%*s%s%-*s|\n", x, " ", centerl1, " ", szTitle[0], TOTAL-centerl1-nl1+1, " "); printf("%*s|%*s|\n", x, " ", TOTAL, " "); printf("%*s|%*s%s%-*s|\n", x, " ", centerl2, " ", szTitle[1], TOTAL-centerl2-nl2+2, " "); printf("%*s+%*.*s+\n\n\n", x, " ", TOTAL, TOTAL, buff); }/* Greeting */ /*! * Imprime opções do menu. */ void PrintMenu(void) { static const char *szMenu[] = { "\x02 1 - Gera vetor (0-1000 rnd).", "\x02 2 - Consulta vetor.", "\x02 3 - Ordena.", "\x02 4 - Media e desvio padrao (1000 casos).", "\x02 5 - Imprimir.", "\x06 51 - Vetor desordenado.", "\x06 52 - Vetor ordenado.", "\x02 6 - Sair.", NULL }; const char **p; char buff[128]; #define SIZE_TAB 8 #undef TOTAL #define TOTAL 42 memset(buff, '-', 126); buff[127] = '\0'; printf("%*s+---Menu%.*s+\n", SIZE_TAB, " ", TOTAL-7, buff); LogMessage("%*s+---Menu%.*s+\n", SIZE_TAB, " ", TOTAL-7, buff); printf("%*s|%*s|\n", SIZE_TAB, " ", TOTAL, " "); LogMessage("%*s|%*s|\n", SIZE_TAB, " ", TOTAL, " "); p = szMenu; while( *p ) { printf("%*s|%*s%s%*s|\n", SIZE_TAB, " ", **p, " ", (*p)+2, (int)(TOTAL - strlen((*p)+2) - **p), " "); LogMessage("%*s|%*s%s%*s|\n", SIZE_TAB, " ", **p, " ", (*p)+2, (int)(TOTAL - strlen((*p)+2) - **p), " "); p++; } printf("%*s|%*s|\n", SIZE_TAB, " ", TOTAL, " "); LogMessage("%*s|%*s|\n", SIZE_TAB, " ", TOTAL, " "); printf("%*s+%.*s+\n\n", SIZE_TAB, " ", TOTAL, buff); LogMessage("%*s+%.*s+\n\n", SIZE_TAB, " ", TOTAL, buff); printf("%*s%s", SIZE_TAB, " ", "OPCAO: "); LogMessage("%*s%s", SIZE_TAB, " ", "OPCAO: "); fflush(stdout); /* force impressao na tela */ }/* PrintMenu */ /*! * Processa opções do usuário. * * \param [in] pOpt - ponteiro para string com a entrada do usuário. * \param [in] opt - opção do usuário na forma enum optMenu. * * \return Uma opção do menu passado como comando.\n * oNone (não faça nada) em caso nenhum comando foi encontrado. * * \remarks pOpt tera uma string truncada em caso usuario inseriu uma * entrada maior que o buffer. * * \warning A opção de entrar o comando em qualquer parte da execução * do programa foi removido. * * \sa GenerateRndArray, get_element, busca_seq, selectsort, * binary_search, ReportSearch, WaitReturn, quick_sort, ReportSort, * get_AverageAndStdDeviation, ReportAverage, PrintArray */ enum eOptMenu ParseOption(const char* pOpt, enum eOptMenu opt) { enum eOptMenu OptRet = oNone; struct SEARCH_REPORT search_rpt; struct SORT_REPORT sel_rpt, qk_rpt; int ele; LogMessage("%d selecionada.\n", opt); switch(opt) { case oGenerateArray: GenerateRndArray(g_ArrayUnsorted, SIZE_OF_ARRAY); break; case oSearch: if( (ele = get_element()) != -1 ) { search_rpt.seq_index = busca_seq(ele, g_ArrayUnsorted, SIZE_OF_ARRAY, &search_rpt.seq_comp); if( !g_bArraySorted ) { selectsort(g_ArrayUnsorted, g_ArraySorted, &sel_rpt.permutations, &sel_rpt.comparasions); g_bArraySorted = TRUE; } search_rpt.bin_index = binary_search(ele, g_ArraySorted, SIZE_OF_ARRAY, &search_rpt.bin_comp); ReportSearch(ele, search_rpt.seq_index != -1, search_rpt.bin_index != -1, &search_rpt); } WaitReturn(); break; case oSort: selectsort(g_ArrayUnsorted, g_ArraySorted, &sel_rpt.permutations, &sel_rpt.comparasions); #if defined(INCLUDE_QUICK_SORT) memcpy(&g_ArraySorted[0], &g_ArrayUnsorted[0], SIZE_OF_ARRAY * sizeof(g_ArrayUnsorted[0])); qk_rpt.comparasions = qk_rpt.permutations = 0; quick_sort(g_ArraySorted, 1, SIZE_OF_ARRAY-1, &qk_rpt.comparasions, &qk_rpt.permutations); #endif ReportSort(&sel_rpt, &qk_rpt); g_bArraySorted = TRUE; WaitReturn(); break; case oSS1000: fprintf(stderr, "Calculando...\n"); get_AverageAndStdDeviation(&search_rpt, &sel_rpt, &qk_rpt, MAX_AVERAGE); ReportAverage(&search_rpt, &sel_rpt, &qk_rpt); WaitReturn(); break; case oPrintUnsorted: PrintArray(g_ArrayUnsorted, SIZE_OF_ARRAY); WaitReturn(); break; case oPrintSorted: PrintArray(g_ArraySorted, SIZE_OF_ARRAY); WaitReturn(); break; default: printf("'%s' opção inválida.\n", pOpt); LogMessage("'%s' opção inválida.\n", pOpt); WaitReturn(); } return OptRet; }/* ParseOption */ /*! Calula Média e desvio padrão das comparações dos * algoritmos busca sequencial, busca binária, ordenação * select sort, quick sort. * * \param [out] s_rpt - ponteiro para a estrutura * pesquisa, com os dados a ser gerado um relatório. * \param [out] ss_rpt - ponteiro para a estrutura * select sort, com os dados a ser gerado um relatório. * \param [out] qks_rpt - ponteiro para a estrutura * quick sort, com os dados a ser gerado um relatório. * \param [in] nsize - número de casos a serem analizados. * * \remarks O cálculo da variância requer a média das comparações, * então não podemos acumular o quadrado da diferença de * x iésimo elemento to vetor com MA (média aritimética), * pois não temos a média, porém podemos acumular o número de * comparções de cada algoritmo para efeito do cálculo da média. * Então é necessário armazenar o número de comparações e * depois subtrair da média e elevar ao quadrado para o cálculo * da variância. Consequentemente temos o desvio padrão. * * \sa GenerateRndArray, busca_seq, selectsort, * binary_search, quick_sort */ void get_AverageAndStdDeviation(struct SEARCH_REPORT *s_rpt, struct SORT_REPORT *ss_rpt, struct SORT_REPORT *qks_rpt, int nsize) { int i, ele, temp; float vseq, vbin, vss, vqks; s_rpt->seq_comp = 0; s_rpt->bin_comp = 0; ss_rpt->comparasions = 0; #if defined(INCLUDE_QUICK_SORT) qks_rpt->comparasions = 0; #endif srand(time(0)); /* * Obtenha as n comparacoes, armazena-as em um vetor * para ser calculado a variancia. */ for( i=0; i < nsize; i++ ) { GenerateRndArray(g_ArrayUnsorted, SIZE_OF_ARRAY); ele = rand() % MAX_ELEMENT; busca_seq(ele, g_ArrayUnsorted, SIZE_OF_ARRAY, &temp); s_rpt->seq_comp += temp; g_nSeqComp[i] = temp; selectsort(g_ArrayUnsorted, g_ArraySorted, &ss_rpt->permutations, &temp); ss_rpt->comparasions += temp; g_nSelComp[i] = temp; #if defined(INCLUDE_QUICK_SORT) memcpy(g_ArraySorted, g_ArrayUnsorted, SIZE_OF_ARRAY * sizeof(g_ArrayUnsorted[0])); temp = 0; quick_sort(g_ArraySorted, 1, SIZE_OF_ARRAY-1, &temp, &qks_rpt->permutations); qks_rpt->comparasions += temp; g_nQkComp[i] = temp; #endif binary_search(ele, g_ArraySorted, SIZE_OF_ARRAY, &temp); s_rpt->bin_comp += temp; g_nBinComp[i] = temp; }/* for */ /* Obtenha a media aritimetica */ s_rpt->seq_average = (float)s_rpt->seq_comp / (float)nsize; s_rpt->bin_average = (float)s_rpt->bin_comp / (float)nsize; ss_rpt->average = (float)ss_rpt->comparasions / (float)nsize; #if defined(INCLUDE_QUICK_SORT) qks_rpt->average = (float)qks_rpt->comparasions / (float)nsize; #endif vseq = vbin = vss = vqks = 0; /* Obtenha a variancia */ for( i=0; i < nsize; i++ ) { vseq += powf(g_nSeqComp[i] - s_rpt->seq_average, 2); vbin += powf(g_nBinComp[i] - s_rpt->bin_average, 2); vss += powf(g_nSelComp[i] - ss_rpt->average, 2); #if defined(INCLUDE_QUICK_SORT) vqks += powf(g_nQkComp[i] - qks_rpt->average, 2); #endif } vseq /= (float)nsize; vbin /= (float)nsize; vss /= (float)nsize; #if defined(INCLUDE_QUICK_SORT) vqks /= (float)nsize; #endif /* Obtenha desvio padrao. */ s_rpt->seq_std_deviation = sqrt(vseq); s_rpt->bin_std_deviation = sqrt(vbin); ss_rpt->std_deviation = sqrt(vss); #if defined(INCLUDE_QUICK_SORT) qks_rpt->std_deviation = sqrt(vqks); #endif }/* get_AverageAndStdDeviation */ /*! * \brief Imprime na tela espere e aguarda pela tecla enter. * * \remarks Esta função só executara as linhas abaixo em caso * a variável global g_bStdinConnectedTotty = TRUE, * entrada padrão esta conectada ao terminal do usuário. * Se o usuário entrar qualquer dado antes de enter ele(s) * serão ignorados. * * \sa MoreInput, EmptyStdIn */ void WaitReturn(void) { if( g_bStdinConnectedTotty ) { if( MoreInput() ) EmptyStdIn(); printf("\nPressione enter para continuar..."); fflush(stdout); EmptyStdIn(); /* espera por enter, qualquer dado entrado sera ignorado */ } }/* WaitReturn */ /*! Gera vetor com nsize elementos aleatório. * O elemento máximo foi defino pela macro * MAX_ELEMENT. * * \param [out] arr[] - vetor onde será * armazenado os valores aleatórios. * \param [in] size - tamanho de arr[]. * * \remarks Observe que 0 foi reservado para busca com * sentinela, então ignoramos esta posição do vetor. * * \sa MAX_ELEMENT */ void GenerateRndArray(int arr[], int size) { int i; srand(time(0)); for( i=1; i < size; i++ ) arr[i] = rand() % MAX_ELEMENT; }/* GenerateRndArray */ /*! * Imprime na tela em forma de uma matriz, * numerando linhas e colunas, facilitando * a identificação de um elemento no vetor. * * \param [in] arr[] - vetor com os elementos * a serem impressos no terminal. * \param [in] size - número de elementos do vetor arr[]. * * \sa LogMessage */ void PrintArray(int arr[], int size) { #define MAX_ELEMENT_PER_LINE 16 int i, line; /* format output */ printf("Elementos do vetor:\n"); printf("%7s", "01:"); LogMessage("%7s", "01:"); for( i=2; i <= MAX_ELEMENT_PER_LINE; i++ ) { printf("%4.2d:", i); LogMessage("%4.2d:", i); } /* * We need to count ith from 0, because we need MAX_ELEMENT * to be include in the line, after that we should break it. */ size--; line = 1; /* count labels of each line. */ for( i=0; i < size; i++ ) { if( i % MAX_ELEMENT_PER_LINE == 0 ) { printf("\n%.2d: %3d", line, arr[i+1]); LogMessage("\n%.2d: %3d", line++, arr[i+1]); }else { printf(", %3d", arr[i+1]); LogMessage(", %3d", arr[i+1]); } }/* for */ putchar('\n'); LogMessage("\n"); fflush(stdout); }/* PrintArray */ /*! * Obtem um elemento. Este elemento é obtido de duas maneiras: * 1. aleatóriamente (entre 0 e MAX_ELEMENT) entrando uma * string vazia. * 2. através da entrada padrão. Neste caso o usuário pode entrar * no máximo 9999, qualquer entrada adicional será ignorado. * * \sa LogMessage, read_input */ int get_element(void) { #undef BUFF_SIZE #define BUFF_SIZE 6 /* xxxx\n\0 */ char buff[BUFF_SIZE]; char *endp; int ele, n, err; printf("Entre elemento a ser pesquisado (em branco gera aleatóriamente): "); LogMessage("Entre elemento a ser pesquisado (em branco gera aleatóriamente): "); fflush(stdout); n = read_input(buff, BUFF_SIZE); if( n == 0 ) { srand(time(0)); ele = rand() % MAX_ELEMENT; printf("Elemento '%d' gerado aleatóriamente.\n", ele); LogMessage("Elemento '%d' gerado aleatóriamente.\n", ele); } else { ele = (int)strtol(buff, &endp, 10); err = errno; if( ele == 0 && buff == endp ) { /* error */ perror("Erro 'get_element'"); LogMessage("Erro 'get_element': %s\n", strerror(err)); ele = -1; }else LogMessage("Elemento '%d' entrado pelo usuário.\n", ele); } return ele; }/* get_element */ /*! * Impreme relatório da pesquisa na saída padrão. * * \param [in] element - elemento que foi pesquisado. * \param [in] f_seq - True se o elemento foi encontrado * pela busca sequencial, False caso contrário. * \param [in] f_bin - True se o elemento foi encontrado * pela busca binária, False caso contrário. * \param [in] sr - ponteiro para a estrutura com os dados * da pesquisa sequencial e binária. * * \sa LogMessage */ void ReportSearch(int element, bool f_seq, bool f_bin, const struct SEARCH_REPORT *sr) { char buff[20]; memset(buff, '=', sizeof(buff)-1); buff[19] = '\0'; printf("Relatório da pesquisa pelo elemento '%d':\n", element); LogMessage("Relatório da pesquisa pelo elemento '%d':\n", element); printf("%20s %-15s %-13s %-14s\n", "Método:", "Comparações:", "Encontrado:", "Índice:"); printf("%.19s %-.13s %-.13s %-.13s\n", buff, buff, buff, buff); LogMessage("%20s %-15s %-13s %-14s\n", "Método:", "Comparações:", "Encontrado:", "Índice:"); LogMessage("%.19s %-.13s %-.13s %-.13s\n", buff, buff, buff, buff); printf("%19s %-13d %-13c %d\n", "sequencial", sr->seq_comp, f_seq ? 'S' : 'N', sr->seq_index); LogMessage("%19s %-13d %-13c %d\n", "sequencial", sr->seq_comp, f_seq ? 'S' : 'N', sr->seq_index); printf("%20s %-13d %-13c %d\n", "binária", sr->bin_comp, f_bin ? 'S' : 'N', sr->bin_index); LogMessage("%20s %-13d %-13c %d\n\n", "binária", sr->bin_comp, f_bin ? 'S' : 'N', sr->bin_index); fflush(stdout); }/* ReportSearch */ /*! * Impreme relatório de ordenação na saída padrão. * * \param [in] sel_rpt - ponteiro para a estrutura com * os dados da pesquisa do algoritmo selectsort. * \param [in] qk_rpt - ponteiro para a estrutura com * os dados da pesquisa do algoritmo quicksort. * * \sa LogMessage */ void ReportSort(const struct SORT_REPORT *sel_rpt, const struct SORT_REPORT *qk_rpt) { char buff[20]; printf("Relatório da ordenação:\n"); LogMessage("Relatório da ordenação:\n"); memset(buff, '=', sizeof(buff)-1); buff[19] = '\0'; printf("%20s %-15s %-15s\n", "Método:", "Comparações:", "Permutações:"); printf("%19s %-13.12s %-13.12s\n", buff, buff, buff); LogMessage("%20s %-15s %-15s\n", "Método:", "Comparações:", "Permutações:"); LogMessage("%19s %-13.12s %-13.12s\n", buff, buff, buff); printf("%19s %-13d %-13d\n", "selectSort", sel_rpt->comparasions, sel_rpt->permutations); #if defined(INCLUDE_QUICK_SORT) LogMessage("%19s %-13d %-13d\n", "selectSort", sel_rpt->comparasions, sel_rpt->permutations); printf("%19s %-13d %-13d\n", "quickSort", qk_rpt->comparasions, qk_rpt->permutations); LogMessage("%19s %-13d %-13d\n\n", "quickSort", qk_rpt->comparasions, qk_rpt->permutations); #else LogMessage("%19s %-13d %-13d\n\n", "selectSort", sel_rpt->comparasions, sel_rpt->permutations); #endif fflush(stdout); }/* ReportSort */ /*! * Impreme relatório das médias e desvio padrão, * na saída padrão. * * \param [in] s_rpt - ponteiro para os dados da * pesquisa sequencial e binária a serem relatadas. * \param [in] ss_rpt - ponteiro para os dados da ordenação * selectsort. * \param [in] qks_rpt - ponteiro para os dados da ordenação * quicksort. * * \sa LogMessage */ void ReportAverage(const struct SEARCH_REPORT *s_rpt, const struct SORT_REPORT *ss_rpt, const struct SORT_REPORT *qks_rpt) { char buff[20]; memset(buff, '=', sizeof(buff)); buff[19] = '\0'; printf("Relatório da média e desvio padão de 1000 casos:\n"); LogMessage("Relatório da média e desvio padão de 1000 casos:\n"); printf("%20s %-13s %s\n", "Método:", "Média:", "Desvio Padrão:"); printf("%.19s %-.12s %.15s\n", buff, buff, buff); LogMessage("%20s %-13s %s\n", "Método:", "Média:", "Desvio Padrão:"); LogMessage("%.19s %-.12s %.15s\n", buff, buff, buff); printf("%19s %-13.2f %.2f\n", "Pesq. sequencial", s_rpt->seq_average, s_rpt->seq_std_deviation); LogMessage("%19s %-13.2f %.2f\n", "Pesq. sequencial", s_rpt->seq_average, s_rpt->seq_std_deviation); printf("%20s %-13.2f %.2f\n", "Pesq. binária", s_rpt->bin_average, s_rpt->bin_std_deviation); LogMessage("%20s %-13.2f %.2f\n", "Pesq. binária", s_rpt->bin_average, s_rpt->bin_std_deviation); printf("%19s %-13.2f %.2f\n", "Ord. selectsort", ss_rpt->average, ss_rpt->std_deviation); #if defined(INCLUDE_QUICK_SORT) LogMessage("%19s %-13.2f %.2f\n", "Ord. selectsort", ss_rpt->average, ss_rpt->std_deviation); printf("%19s %-13.2f %.2f\n", "Ord. quicksort", qks_rpt->average, qks_rpt->std_deviation); LogMessage("%19s %-13.2f %.2f\n\n", "Ord. quicksort", qks_rpt->average, qks_rpt->std_deviation); #else LogMessage("%19s %-13.2f %.2f\n\n", "Ord. selectsort", ss_rpt->average, ss_rpt->std_deviation); #endif fflush(stdout); }/* ReportAverage */