From 5fc433cf5695ebb2c95ad7a5c42e4fac9fdc219f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre=20=E2=9C=8F?= Date: Sat, 22 Oct 2016 01:09:46 +0200 Subject: [PATCH] Restructuration de la sortie verbeuse --- include/display.h | 13 +++++ src/compress.c | 43 ++++++---------- src/display.c | 125 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 125 insertions(+), 56 deletions(-) diff --git a/include/display.h b/include/display.h index d6ad615..dcbd4bb 100644 --- a/include/display.h +++ b/include/display.h @@ -2,6 +2,7 @@ #define __IN303_DISPLAY_H__ #include "huftree.h" +#include /** * Afficher sur la sortie standard l'arbre passé @@ -9,4 +10,16 @@ */ void printTree(HufTree tree); +/** + * Afficher sur la sortie standard le tableau associant les caractères + * à leur fréquence d'apparition passé en argument + */ +void printFrequenciesTable(double*, size_t); + +/** + * Afficher sur la sortie standard le tableau associant les caractères + * à leur étiquette passé en argument + */ +void printLabelsTable(char**, size_t); + #endif diff --git a/src/compress.c b/src/compress.c index 3fea317..3115576 100644 --- a/src/compress.c +++ b/src/compress.c @@ -42,42 +42,31 @@ double* _createFrequencies(const char *filepath) { } void compress(const char *filepath) { - double *frequencies = _createFrequencies(filepath); + printVerbose("Calcul des fréquences d'apparition de chaque caractère\n"); + double *frequencies = _createFrequencies(filepath); - if (IS_VERBOSE) { - printf("--- 1 : CALCUL DES FRÉQUENCES ---\n\n"); - double sum = 0; - - for (size_t i = 0; i < NUM_CHARS; i++) { - if (frequencies[i] != 0) { - sum += frequencies[i]; - printf("%1c (%3d) : %4f\n", (int) i, (int) i, frequencies[i]); - } - } - - printf("Total : %f\n\n", sum); - } + if (isVerbose()) { + printFrequenciesTable(frequencies, NUM_CHARS); + } + printVerbose("\nConstruction de l'arbre de Huffman\n"); HufTree tree = createTree(frequencies); - if (IS_VERBOSE) { - printf("--- 2 : CONSTRUCTION DE L'ARBRE ---\n\n"); - printf("Arbre à %zu sommets\n\n", tree.size); + free(frequencies); + frequencies = NULL; + + if (isVerbose()) { printTree(tree); } + printVerbose("\nÉtiquetage des feuilles de l'arbre\n"); char** labels = createTreeLabels(tree); - if (IS_VERBOSE) { - printf("\n\n--- 3 : ATTRIBUTION DES CODES ---\n\n"); - for (size_t i = 0; i < NUM_CHARS; i++) { - if (labels[i] != NULL) { - printf("%1c (%3d) : %s\n", (int) i, (int) i, labels[i]); - } - } - } + freeTree(tree); + + if (isVerbose()) { + printLabelsTable(labels, NUM_CHARS); + } - free(frequencies); - freeTree(tree); freeTreeLabels(labels); } diff --git a/src/display.c b/src/display.c index 92201b8..27d69a1 100644 --- a/src/display.c +++ b/src/display.c @@ -1,48 +1,115 @@ #include "../include/display.h" #include "../include/common.h" #include +#include +#include + +/** + * Détermine la profondeur de l'arbre binaire + * à partir du sommet donné + */ +static int _maxDepth(HufVertex); /** * Affiche l'arborescence à partir du sommet donné, * indenté sur le niveau donné */ -static void _printVertex(HufVertex, int level, int is_first); +static void _printVertex(HufVertex, wchar_t*, int); -void _printVertex(HufVertex vert, int level, int is_first) { - // affichage des n espaces d'indentation - for (int i = 0; i < level; i++) { - if (i < level - 1) { - printf("│ "); - } else { - printf("├───"); - } - } +/** + * Transforme le caractère donné en espace s'il est + * non-imprimable, ou le laisse tel quel sinon + */ +static char _safeChar(char input); +void _printVertex(HufVertex vert, wchar_t *buffer, int length) { if (vert.child_l != NULL && vert.child_r != NULL) { - // affichage d'un noeud contenant des enfants - // un tel noeud n'a pas de nom, on utilise un caractère - // selon sa position - const char *name; + // Affichage d'un sommet avec enfants, on montre + // la probabilité somme des enfants + printf("■\n", vert.frequency); - if (level == 0) { - name = "▅"; - } else { - if (is_first) { - name = "┬"; - } else { - name = "┼"; - } - } + // Affichage du fils gauche. Augmentation du préfixe + // pour l'affichage des enfants du fils gauche + buffer[length] = '\0'; + printf("%ls├── ", buffer); - printf("%s (%4f)\n", name, vert.frequency); - _printVertex(*vert.child_l, level + 1, TRUE); - _printVertex(*vert.child_r, level + 1, FALSE); + buffer[length] = L'│'; + buffer[length + 1] = ' '; + buffer[length + 2] = ' '; + buffer[length + 3] = ' '; + buffer[length + 4] = '\0'; + _printVertex(*vert.child_l, buffer, length + 4); + + // Affichage du fils droite. Augmentation du préfixe + // pour l'affichage des enfants du fils droit + buffer[length] = '\0'; + printf("%ls└── ", buffer); + + buffer[length] = ' '; + _printVertex(*vert.child_r, buffer, length + 4); } else { - // c'est une feuille, affichage du sommet - printf("%c (%4f)\n", vert.character, vert.frequency); + // Affichage d'une feuille de l'arbre, correspondant + // à un caractère du corpus + printf("%c\n", vert.character, vert.frequency); } } +int _maxDepth(HufVertex vert) { + if (vert.child_l != NULL && vert.child_r != NULL) { + int left = _maxDepth(*vert.child_l); + int right = _maxDepth(*vert.child_r); + + return (left > right ? left : right) + 1; + } else { + return 1; + } +} + void printTree(HufTree tree) { - _printVertex(*tree.root, 0, TRUE); + // Allocation d'un tampon suffisamment grand pour contenir + // les indentations des sommets les plus profonds de l'arbre + wchar_t *buffer = malloc(_maxDepth(*tree.root) * 4 * sizeof(*buffer)); + _printVertex(*tree.root, buffer, 0); + free(buffer); +} + +char _safeChar(char input) { + if (input < 32 || input == 127) { + return ' '; + } + + return input; +} + +void printFrequenciesTable(double* table, size_t size) { + printf("╭─┬───┬─────────╮\n"); + printf("│C│num│fréquence│\n"); + printf("├─┼───┼─────────┤\n"); + + double sum = 0; + + for (size_t i = 0; i < size; i++) { + if (table[i] != 0) { + printf("│%c│%3d│%9lf│\n", _safeChar(i), (int) i, table[i]); + sum += table[i]; + } + } + + printf("├─┴───┼─────────┤\n"); + printf("│Total│%9lf│\n", sum); + printf("╰─────┴─────────╯\n"); +} + +void printLabelsTable(char** table, size_t size) { + printf("╭─┬───┬────────────────╮\n"); + printf("│C│num│ étiquette│\n"); + printf("├─┼───┼────────────────┤\n"); + + for (size_t i = 0; i < size; i++) { + if (table[i] != 0) { + printf("│%c│%3d│%16s│\n", _safeChar(i), (int) i, table[i]); + } + } + + printf("╰─┴───┴────────────────╯\n"); }