Correction des indentations (tabulations -> espaces)
This commit is contained in:
parent
16e6a0c5ca
commit
f7378d4707
|
@ -8,20 +8,20 @@
|
||||||
*/
|
*/
|
||||||
typedef struct HufVertex HufVertex;
|
typedef struct HufVertex HufVertex;
|
||||||
struct HufVertex {
|
struct HufVertex {
|
||||||
// Indique la fréquence d'apparition de la lettre du sommet
|
// Indique la fréquence d'apparition de la lettre du sommet
|
||||||
// dans le corpus original, ou bien la somme des fréquences
|
// dans le corpus original, ou bien la somme des fréquences
|
||||||
// de ses enfants (si ce n'est pas une feuille)
|
// de ses enfants (si ce n'est pas une feuille)
|
||||||
double frequency;
|
double frequency;
|
||||||
|
|
||||||
// Caractère du corpus original associé à ce sommet. Uniquement
|
// Caractère du corpus original associé à ce sommet. Uniquement
|
||||||
// valable pour les feuilles. Pour les autres sommets, la valeur
|
// valable pour les feuilles. Pour les autres sommets, la valeur
|
||||||
// de (character) n'est pas garantie
|
// de (character) n'est pas garantie
|
||||||
char character;
|
char character;
|
||||||
|
|
||||||
// Pointeurs vers les deux enfants de ce sommet. Ils valent tous
|
// Pointeurs vers les deux enfants de ce sommet. Ils valent tous
|
||||||
// deux NULL si le sommet est une feuille. À noter qu'un sommet
|
// deux NULL si le sommet est une feuille. À noter qu'un sommet
|
||||||
// a toujours 0 ou 2 enfants car un arbre de Huffman est binaire
|
// a toujours 0 ou 2 enfants car un arbre de Huffman est binaire
|
||||||
HufVertex *child_l, *child_r;
|
HufVertex *child_l, *child_r;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,11 +29,11 @@ struct HufVertex {
|
||||||
*/
|
*/
|
||||||
typedef struct HufTree HufTree;
|
typedef struct HufTree HufTree;
|
||||||
struct HufTree {
|
struct HufTree {
|
||||||
// Pointeur sur la racine de l'arbre
|
// Pointeur sur la racine de l'arbre
|
||||||
HufVertex *root;
|
HufVertex *root;
|
||||||
|
|
||||||
// Quantité de sommets dans l'arbre
|
// Quantité de sommets dans l'arbre
|
||||||
size_t size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -15,42 +15,42 @@
|
||||||
static double* _createFrequencies(const char*);
|
static double* _createFrequencies(const char*);
|
||||||
|
|
||||||
double* _createFrequencies(const char *filepath) {
|
double* _createFrequencies(const char *filepath) {
|
||||||
double *frequencies = malloc(NUM_CHARS * sizeof(*frequencies));
|
double *frequencies = malloc(NUM_CHARS * sizeof(*frequencies));
|
||||||
int totalChars = 0;
|
int totalChars = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < NUM_CHARS; i++) {
|
for (size_t i = 0; i < NUM_CHARS; i++) {
|
||||||
frequencies[i] = 0;
|
frequencies[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ouverture du fichier en lecture seule, et comptage
|
// Ouverture du fichier en lecture seule, et comptage
|
||||||
// des occurences de chaque caractère ASCII ainsi que
|
// des occurences de chaque caractère ASCII ainsi que
|
||||||
// du nombre total de caractères
|
// du nombre total de caractères
|
||||||
FILE *file = fopen(filepath, "r");
|
FILE *file = fopen(filepath, "r");
|
||||||
|
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
fprintf(
|
fprintf(
|
||||||
stderr, "Impossible d'ouvrir '%s' : %s\n",
|
stderr, "Impossible d'ouvrir '%s' : %s\n",
|
||||||
filepath, strerror(errno)
|
filepath, strerror(errno)
|
||||||
);
|
);
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
char current;
|
char current;
|
||||||
|
|
||||||
while ((current = fgetc(file)) != EOF) {
|
while ((current = fgetc(file)) != EOF) {
|
||||||
frequencies[(size_t) current]++;
|
frequencies[(size_t) current]++;
|
||||||
totalChars++;
|
totalChars++;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
// Conversion des effectifs des caractères en fréquences
|
// Conversion des effectifs des caractères en fréquences
|
||||||
for (size_t i = 0; i < NUM_CHARS; i++) {
|
for (size_t i = 0; i < NUM_CHARS; i++) {
|
||||||
frequencies[i] /= totalChars;
|
frequencies[i] /= totalChars;
|
||||||
}
|
}
|
||||||
|
|
||||||
return frequencies;
|
return frequencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
void compress(const char *filepath) {
|
void compress(const char *filepath) {
|
||||||
|
@ -62,17 +62,17 @@ void compress(const char *filepath) {
|
||||||
}
|
}
|
||||||
|
|
||||||
printVerbose("\nConstruction de l'arbre de Huffman\n");
|
printVerbose("\nConstruction de l'arbre de Huffman\n");
|
||||||
HufTree tree = createTree(frequencies);
|
HufTree tree = createTree(frequencies);
|
||||||
|
|
||||||
free(frequencies);
|
free(frequencies);
|
||||||
frequencies = NULL;
|
frequencies = NULL;
|
||||||
|
|
||||||
if (isVerbose()) {
|
if (isVerbose()) {
|
||||||
printTree(tree);
|
printTree(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
printVerbose("\nÉtiquetage des feuilles de l'arbre\n");
|
printVerbose("\nÉtiquetage des feuilles de l'arbre\n");
|
||||||
char** labels = createTreeLabels(tree);
|
char** labels = createTreeLabels(tree);
|
||||||
|
|
||||||
freeTree(tree);
|
freeTree(tree);
|
||||||
|
|
||||||
|
@ -80,5 +80,5 @@ void compress(const char *filepath) {
|
||||||
printLabelsTable(labels, NUM_CHARS);
|
printLabelsTable(labels, NUM_CHARS);
|
||||||
}
|
}
|
||||||
|
|
||||||
freeTreeLabels(labels);
|
freeTreeLabels(labels);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,15 +26,15 @@ void printTree(HufTree tree) {
|
||||||
// Allocation d'un tampon suffisamment grand pour contenir
|
// Allocation d'un tampon suffisamment grand pour contenir
|
||||||
// les indentations des sommets les plus profonds de l'arbre
|
// les indentations des sommets les plus profonds de l'arbre
|
||||||
wchar_t *buffer = malloc(_maxDepth(*tree.root) * 4 * sizeof(*buffer));
|
wchar_t *buffer = malloc(_maxDepth(*tree.root) * 4 * sizeof(*buffer));
|
||||||
_printVertex(*tree.root, buffer, 0);
|
_printVertex(*tree.root, buffer, 0);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _printVertex(HufVertex vert, wchar_t *buffer, int length) {
|
void _printVertex(HufVertex vert, wchar_t *buffer, int length) {
|
||||||
if (vert.child_l != NULL && vert.child_r != NULL) {
|
if (vert.child_l != NULL && vert.child_r != NULL) {
|
||||||
// Affichage d'un sommet avec enfants, on montre
|
// Affichage d'un sommet avec enfants, on montre
|
||||||
// la probabilité somme des enfants
|
// la probabilité somme des enfants
|
||||||
printf("■\n");
|
printf("■\n");
|
||||||
|
|
||||||
// Affichage du fils gauche. Augmentation du préfixe
|
// Affichage du fils gauche. Augmentation du préfixe
|
||||||
// pour l'affichage des enfants du fils gauche
|
// pour l'affichage des enfants du fils gauche
|
||||||
|
@ -55,11 +55,11 @@ void _printVertex(HufVertex vert, wchar_t *buffer, int length) {
|
||||||
|
|
||||||
buffer[length] = ' ';
|
buffer[length] = ' ';
|
||||||
_printVertex(*vert.child_r, buffer, length + 4);
|
_printVertex(*vert.child_r, buffer, length + 4);
|
||||||
} else {
|
} else {
|
||||||
// Affichage d'une feuille de l'arbre, correspondant
|
// Affichage d'une feuille de l'arbre, correspondant
|
||||||
// à un caractère du corpus
|
// à un caractère du corpus
|
||||||
printf("%c\n", _safeChar(vert.character));
|
printf("%c\n", _safeChar(vert.character));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int _maxDepth(HufVertex vert) {
|
int _maxDepth(HufVertex vert) {
|
||||||
|
|
|
@ -4,30 +4,30 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trouver les deux sommets de valeur la plus faible parmi
|
* Trouver les deux sommets de valeur la plus faible parmi
|
||||||
* tous les sommets pointés par le tableau. Place l'indice
|
* tous les sommets pointés par le tableau. Place l'indice
|
||||||
* du minimum dans `min` et de l'avant-dernier dans `sec`.
|
* du minimum dans `min` et de l'avant-dernier dans `sec`.
|
||||||
*/
|
*/
|
||||||
static void _findMinimalVertices(HufVertex**, size_t, size_t* min, size_t* sec);
|
static void _findMinimalVertices(HufVertex**, size_t, size_t* min, size_t* sec);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Libérer récursivement la mémoire occupée par le sommet
|
* Libérer récursivement la mémoire occupée par le sommet
|
||||||
* donné ainsi que celle de tous ses enfants (s'il en a).
|
* donné ainsi que celle de tous ses enfants (s'il en a).
|
||||||
*/
|
*/
|
||||||
static void _freeTreeVertex(HufVertex*);
|
static void _freeTreeVertex(HufVertex*);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Créer une nouvelle chaîne contenant la chaîne donnée
|
* Créer une nouvelle chaîne contenant la chaîne donnée
|
||||||
* suffixée du caractère donné
|
* suffixée du caractère donné
|
||||||
*/
|
*/
|
||||||
static char* _appendToString(char*, size_t, char);
|
static char* _appendToString(char*, size_t, char);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remplit le tableau d'étiquettes données avec les étiquettes
|
* Remplit le tableau d'étiquettes données avec les étiquettes
|
||||||
* des feuilles trouvées dans la sous-partie de l'arbre dont
|
* des feuilles trouvées dans la sous-partie de l'arbre dont
|
||||||
* le sommet donné est la racine. Toutes les étiquettes ajoutées
|
* le sommet donné est la racine. Toutes les étiquettes ajoutées
|
||||||
* au tableau seront préfixées de la chaîne passée en paramètre
|
* au tableau seront préfixées de la chaîne passée en paramètre
|
||||||
*/
|
*/
|
||||||
static void _labelVertex(HufVertex, char**, char*, size_t);
|
static void _labelVertex(HufVertex, char**, char*, size_t);
|
||||||
|
|
||||||
HufTree createTree(double* frequencies) {
|
HufTree createTree(double* frequencies) {
|
||||||
|
|
20
src/main.c
20
src/main.c
|
@ -36,22 +36,22 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'V':
|
case 'V':
|
||||||
args->verbose = TRUE;
|
args->verbose = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARGP_KEY_ARG:
|
case ARGP_KEY_ARG:
|
||||||
// Consommation de tous les fichiers en argument
|
// Consommation de tous les fichiers en argument
|
||||||
// et arrêt du parsage
|
// et arrêt du parsage
|
||||||
args->files = &state->argv[state->next - 1];
|
args->files = &state->argv[state->next - 1];
|
||||||
state->next = state->argc;
|
state->next = state->argc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARGP_KEY_NO_ARGS:
|
case ARGP_KEY_NO_ARGS:
|
||||||
argp_usage(state);
|
argp_usage(state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ARGP_ERR_UNKNOWN;
|
return ARGP_ERR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue