Renommage name -> value, frequency -> count dans HufTree
Initialisation de value à -1 lorsque aucune valeur
This commit is contained in:
parent
fdbdeb1756
commit
e915bd3080
|
@ -16,15 +16,13 @@ typedef struct ReadBuffer ReadBuffer;
|
||||||
typedef struct HufVertex HufVertex;
|
typedef struct HufVertex HufVertex;
|
||||||
typedef HufVertex* HufTree;
|
typedef HufVertex* HufTree;
|
||||||
struct HufVertex {
|
struct HufVertex {
|
||||||
// Indique la fréquence d'apparition de la lettre du sommet
|
// Caractère associé à ce sommet ou -1 s'il n'y a aucun caractère
|
||||||
// dans le corpus original, ou bien la somme des fréquences
|
// associé (notamment s'il s'agit d'une branche)
|
||||||
// de ses enfants (si ce n'est pas une feuille)
|
unsigned int value;
|
||||||
double frequency;
|
|
||||||
|
|
||||||
// Caractère du corpus original associé à ce sommet. Uniquement
|
// Indique l'effectif du caractère associée à ce sommet
|
||||||
// valable pour les feuilles. Pour les autres sommets, la valeur
|
// dans le fichier source, ou -1 s'il n'y a aucun caractère associé
|
||||||
// de `name` n'est pas garantie
|
bytecount count;
|
||||||
int name;
|
|
||||||
|
|
||||||
// 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
|
||||||
|
|
|
@ -12,6 +12,11 @@ void decompress(FILE* source, FILE* dest) {
|
||||||
fread(&original_count, sizeof(original_count), 1, source);
|
fread(&original_count, sizeof(original_count), 1, source);
|
||||||
printVerbose("Lecture du nombre de caractères : %d.\n", original_count);
|
printVerbose("Lecture du nombre de caractères : %d.\n", original_count);
|
||||||
|
|
||||||
|
if (original_count == 0) {
|
||||||
|
// Cas particulier : fichier vide, rien à restituer
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// ÉTAPE 2 : reconstruction de l'arbre à partir des données linéarisées
|
// ÉTAPE 2 : reconstruction de l'arbre à partir des données linéarisées
|
||||||
printVerbose("Reconstruction de l'arbre de Huffman.\n");
|
printVerbose("Reconstruction de l'arbre de Huffman.\n");
|
||||||
ReadBuffer input = createReadBuffer(source);
|
ReadBuffer input = createReadBuffer(source);
|
||||||
|
@ -48,7 +53,7 @@ void decompress(FILE* source, FILE* dest) {
|
||||||
|
|
||||||
// La valeur de la feuille trouvée est le caractère compressé :
|
// La valeur de la feuille trouvée est le caractère compressé :
|
||||||
// on l'écrit dans le fichier
|
// on l'écrit dans le fichier
|
||||||
fputc(current->name, dest);
|
fputc(current->value, dest);
|
||||||
wrote_count++;
|
wrote_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ void _subPrintTree(HufTree tree, wchar_t* buffer, int length) {
|
||||||
} 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
|
||||||
printVerbose("%c\n", _safeChar(tree->name));
|
printVerbose("%c\n", _safeChar(tree->value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,8 +48,8 @@ HufTree createTree(bytecount* counts) {
|
||||||
if (counts[i] > 0) {
|
if (counts[i] > 0) {
|
||||||
remaining[next_index] = malloc(sizeof(*remaining[next_index]));
|
remaining[next_index] = malloc(sizeof(*remaining[next_index]));
|
||||||
|
|
||||||
remaining[next_index]->name = i;
|
remaining[next_index]->value = i;
|
||||||
remaining[next_index]->frequency = counts[i];
|
remaining[next_index]->count = counts[i];
|
||||||
remaining[next_index]->child_l = NULL;
|
remaining[next_index]->child_l = NULL;
|
||||||
remaining[next_index]->child_r = NULL;
|
remaining[next_index]->child_r = NULL;
|
||||||
|
|
||||||
|
@ -80,7 +80,8 @@ HufTree createTree(bytecount* counts) {
|
||||||
// Création d'un sommet parent P pour A et B
|
// Création d'un sommet parent P pour A et B
|
||||||
HufVertex* parent = malloc(sizeof(*parent));
|
HufVertex* parent = malloc(sizeof(*parent));
|
||||||
|
|
||||||
parent->frequency = min_vert->frequency + sec_min_vert->frequency;
|
parent->value = -1;
|
||||||
|
parent->count = min_vert->count + sec_min_vert->count;
|
||||||
parent->child_l = min_vert;
|
parent->child_l = min_vert;
|
||||||
parent->child_r = sec_min_vert;
|
parent->child_r = sec_min_vert;
|
||||||
|
|
||||||
|
@ -118,8 +119,8 @@ void _findMinimalVertices(
|
||||||
size_t* min_index, size_t* sec_min_index
|
size_t* min_index, size_t* sec_min_index
|
||||||
) {
|
) {
|
||||||
// Initialisation de telle sorte qu'initialement
|
// Initialisation de telle sorte qu'initialement
|
||||||
// on ait `freq(min_index) < freq(sec_min_index)`
|
// on ait `count(min_index) < count(sec_min_index)`
|
||||||
if (vertices[0]->frequency < vertices[1]->frequency) {
|
if (vertices[0]->count < vertices[1]->count) {
|
||||||
*min_index = 0;
|
*min_index = 0;
|
||||||
*sec_min_index = 1;
|
*sec_min_index = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -128,14 +129,14 @@ void _findMinimalVertices(
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 2; i < size; i++) {
|
for (size_t i = 2; i < size; i++) {
|
||||||
double freq = vertices[i]->frequency;
|
double freq = vertices[i]->count;
|
||||||
|
|
||||||
if (freq < vertices[*min_index]->frequency) {
|
if (freq < vertices[*min_index]->count) {
|
||||||
// Sommet de valeur inférieure au minimum trouvé, la valeur
|
// Sommet de valeur inférieure au minimum trouvé, la valeur
|
||||||
// devient le nouveau minimum, le minimum devient second minimum
|
// devient le nouveau minimum, le minimum devient second minimum
|
||||||
*sec_min_index = *min_index;
|
*sec_min_index = *min_index;
|
||||||
*min_index = i;
|
*min_index = i;
|
||||||
} else if (freq < vertices[*sec_min_index]->frequency) {
|
} else if (freq < vertices[*sec_min_index]->count) {
|
||||||
// Sommet de valeur entre le minimum et le second minimum trouvé,
|
// Sommet de valeur entre le minimum et le second minimum trouvé,
|
||||||
// la valeur devient le nouveau second minimum
|
// la valeur devient le nouveau second minimum
|
||||||
*sec_min_index = i;
|
*sec_min_index = i;
|
||||||
|
@ -163,7 +164,7 @@ void writeTree(HufTree tree, WriteBuffer* buffer) {
|
||||||
|
|
||||||
// Écriture de la valeur du sommet
|
// Écriture de la valeur du sommet
|
||||||
for (int i = 7; i >= 0; i--) {
|
for (int i = 7; i >= 0; i--) {
|
||||||
putBuffer((tree->name & (1 << i)) != 0, buffer);
|
putBuffer((tree->value & (1 << i)) != 0, buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,17 +177,20 @@ HufTree readTree(ReadBuffer* buffer) {
|
||||||
|
|
||||||
if (bit == 1) {
|
if (bit == 1) {
|
||||||
// Sommet avec enfants
|
// Sommet avec enfants
|
||||||
|
tree->value = -1;
|
||||||
|
tree->count = -1;
|
||||||
tree->child_l = readTree(buffer);
|
tree->child_l = readTree(buffer);
|
||||||
tree->child_r = readTree(buffer);
|
tree->child_r = readTree(buffer);
|
||||||
} else if (bit == 0) {
|
} else if (bit == 0) {
|
||||||
// Feuille de l'arbre
|
// Feuille de l'arbre
|
||||||
int name = 0;
|
int value = 0;
|
||||||
|
|
||||||
for (int i = 7; i >= 0; i--) {
|
for (int i = 7; i >= 0; i--) {
|
||||||
name |= getBuffer(buffer) << i;
|
value |= getBuffer(buffer) << i;
|
||||||
}
|
}
|
||||||
|
|
||||||
tree->name = name;
|
tree->value = value;
|
||||||
|
tree->count = 0;
|
||||||
tree->child_l = NULL;
|
tree->child_l = NULL;
|
||||||
tree->child_r = NULL;
|
tree->child_r = NULL;
|
||||||
}
|
}
|
||||||
|
@ -241,7 +245,7 @@ void _labelVertex(HufVertex vertex, char** labels, char* label, size_t length) {
|
||||||
} else {
|
} else {
|
||||||
// Si le sommet est une feuille, étiquetage du caractère
|
// Si le sommet est une feuille, étiquetage du caractère
|
||||||
// associé avec l'étiquette passée en paramètre. Fin de la récursion
|
// associé avec l'étiquette passée en paramètre. Fin de la récursion
|
||||||
labels[vertex.name] = label;
|
labels[vertex.value] = label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue