Exercice 1 Métropole – Bac NSI 2025 – Jour 2
Le codage de Shannon-Fano est un système de codage utilisé pour la compression sans pertes de données. Il a été mis au point par Robert Fano d'après une idée de Claude Shannon.
mots clés: arbres binaires, programmation
🔎 Voir les exercices similaires ↓
Métropole – Bac NSI 2025 – Jour 2 Énoncé de l'exercice 1
Cet exercice porte sur les arbres binaires et la programmation Python.
Le codage de Shannon-Fano est un système de codage utilisé pour la compression sans pertes de données. Il a été mis au point par Robert Fano d’après une idée de Claude Shannon.
Partie A
Dans cette partie, on va étudier l’utilisation des arbres de codage.
Un arbre de codage est un arbre binaire où chaque feuille contient un symbole du texte que l’on souhaite coder. Le code binaire d’un symbole s’obtient alors en concaténant les 0 et les 1 sur les branches qui mènent de la racine à la feuille contenant ce symbole. Par exemple, pour l’arbre de codage donné en Figure 1, le symbole c est codé par le mot binaire 1101, tandis que d est codé par le mot binaire 11000. Les codes binaires des symboles ne sont donc pas tous de la même taille. Pour décoder un mot binaire, il suffit de descendre dans l’arbre, depuis la racine, selon les 0 et les 1 qu’on lit jusqu’à trouver une feuille (et donc un symbole), puis de recommencer avec la suite du mot binaire pour décoder les symboles suivants.

Écrire le mot binaire qui sera utilisé pour encoder le caractère espace, représenté par le symbole _ dans l’arbre.
Déterminer le texte codé par le mot binaire 0001110101111110011001.
Citer le type de parcours de l’arbre qui permettrait d’obtenir les symboles classés par taille d’encodage croissante.
Partie B
Dans cette partie, on va utiliser le codage de Shannon-Fano pour encoder le texte :
je pense, donc je suis
Dans la méthode de Shannon-Fano, l’arbre de codage est calculé pour un texte donné par l’algorithme suivant.
Étape 1 : classer les symboles du texte par nombre d’occurrences croissant ;
Étape 2 : en gardant le classement obtenu, séparer les symboles en deux sous-groupes de sorte que les totaux des nombres d’occurrences soient les plus proches possibles dans les deux sous-groupes ;
Étape 3 : placer tous les symboles du premier groupe dans le fils gauche (côté étiqueté par 1), et ceux du second groupe dans le fils droit (côté étiqueté par 0) ;
Étape 4 : recommencer récursivement pour chacun des sous-groupes jusqu’à ce qu’ils n’aient plus qu’un seul symbole ; on a alors une feuille étiquetée par ce symbole.
Après avoir classé les symboles par nombre d’occurrences croissant (étape 1), on obtient le tableau suivant :
| symbole | i | u | c | o | d | , | p | n | j | s | _ | e |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| nombre d’occurrences | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 2 | 2 | 3 | 4 | 4 |
Justifier par le calcul que l’étape 2 mène à la situation illustrée par la Figure 2.

En appliquant l’algorithme de Shannon-Fano, on peut obtenir l’arbre de la Figure 3.

On rappelle qu’un arbre réduit à un seul nœud, c’est-à-dire réduit à une feuille, est de hauteur 0.
Donner la hauteur de l’arbre de la Figure 3 et préciser dans le contexte de l’exercice ce qu’elle représente.
On rappelle que dans le code ASCII, chaque symbole est codé sur un octet.
Justifier, en comparant le codage ASCII et le codage de Shannon-Fano, que ce second codage permet d’utiliser environ deux fois moins d’octets pour le texte : je pense, donc je suis
Dessiner, en vous inspirant de l’arbre de la Figure 1, un arbre de codage qui permettrait d’encoder le mot « chiffrer » en utilisant l’algorithme de Shannon-Fano.
Partie C
Dans cette partie, on souhaite écrire une fonction Python qui donnera le mot binaire obtenu pour coder un texte avec l’algorithme de Shannon-Fano. On commence par la fonction creer_dico_occ :
def creer_dico_occ(texte):
"""renvoie un dictionnaire dont les clés sont les
symboles de texte et les valeurs associées leur
nombre d'occurences dans texte"""
dico = {}
for symbole in texte:
if symbole in dico:
dico[symbole] = ... # ligne 8
else:
dico[symbole] = ... # ligne 10
return dico
Recopier et compléter les lignes 8 et 10 du code de la fonction creer_dico_occ.
On dispose d’une fonction creer_tab_trie qui prend en paramètre un dictionnaire construit avec la fonction creer_dico_occ et qui renvoie une liste de tuples classés dans l’ordre croissant d’occurrences des symboles.
Par exemple :
>>> texte = 'je pense, donc je suis'
>>> dico = creer_dico_occ(texte)
>>> creer_tab_trie(dico)
[('i', 1), ('u', 1), ('c', 1), ('o', 1), ('d', 1), (',', 1),
('p', 1), ('n', 2), ('j', 2), ('s', 3), (' ', 4), ('e', 4)]
Écrire une fonction somme_occ qui prend en paramètres un tableau tab de tuples (symbole, nb_occ) et qui renvoie la somme des nombres d’occurrences des symboles du tableau. Les tuples utilisés sont de même structure que l’élément renvoyé dans l’exemple précédent.
On suppose pour la suite qu’on dispose d’une fonction separe qui sépare un tableau trié en deux sous-tableaux de manière à ce que les sommes de ces derniers soient les plus proches possible :
def separe(tab):
moitie = somme_occ(tab) // 2
somme = 0
i = 0
while moitie > somme:
somme = somme + tab[i][1]
i = i + 1
tab1 = [tab[k] for k in range(0, i)]
tab2 = [tab[k] for k in range(i, len(tab))]
return tab1, tab2
Recopier et compléter les lignes 9 et 11 du code de la fonction récursive shannon qui prend en paramètres un caractère symbole et un tableau trié tab et qui renvoie l’écriture binaire associée à symbole dans le tableau tab.
def shannon(symbole, tab):
"""renvoie l'écriture binaire associée à symbole
dans le tableau trié tab"""
if len(tab) == 1:
return ""
else:
t1, t2 = separe(tab)
if symbole in [elt[0] for elt in t1]:
return "1" + ... # ligne 9
else:
return "0" + ... # ligne 11
Décrire ce qui garantit la terminaison de la fonction récursive shannon.
Écrire une fonction encode_shannon qui prend en paramètre un texte de type str et renvoie un mot binaire de type str obtenu après encodage par l’algorithme de Shannon-Fano.
On pourra utiliser les fonctions vues précédemment qui sont recensées ci-après.
| Fonctions disponibles | |
|---|---|
| creer_dico_occ(texte) | renvoie un dictionnaire dont les clés sont les symboles du texte et les valeurs associées leur nombre d’occurrences |
| creer_tab_trie(dico) | renvoie la liste créée à partir d’un dictionnaire de couples (symbole, nb_occ) |
| separe(tab) | renvoie le tuple composé des 2 sous-tableaux triés avec des sommes d’occurrences proches |
| shannon(symbole, tab) | renvoie l’écriture binaire associée au symbole dans le tableau trié tab |
Métropole – Bac NSI 2025 – Jour 2 Correction de l'exercice 1
Partie A – Lecture et décodage d’un arbre de codage
1. Code de l’espace
On lit les étiquettes des branches de la racine jusqu’à la feuille _ : 0 (à droite), puis 1, puis 0. Le caractère espace est codé par 010.
2. Décodage de 0001110101111110011001
On descend dans l’arbre depuis la racine ; dès qu’on atteint une feuille, on note le symbole et on repart de la racine :
| Bits | 00 | 011 | 1010 | 1111 | 11001 | 1001 |
|---|---|---|---|---|---|---|
| Symbole | e | s | p | i | o | n |
Le texte codé est espion.
3. Parcours
Un parcours en largeur : il visite les nœuds niveau par niveau, donc les feuilles par profondeur croissante, c’est-à-dire par longueur de code croissante.
Partie B – Codage de Shannon-Fano
4. Étape 2
Le total des occurrences vaut 7 × 1 + 2 + 2 + 3 + 4 + 4 = 22. En gardant l’ordre, le groupe i, u, c, o, d, ‘,’, p, n, j totalise 7 + 2 + 2 = 11, et le groupe s, _, e totalise 3 + 4 + 4 = 11 : les deux sommes sont égales, c’est la séparation la plus équilibrée possible.
5. Hauteur de l’arbre
La hauteur de l’arbre de la Figure 3 est 5 (feuilles o et d). C’est la longueur du code le plus long (5 bits).
6. Comparaison avec le code ASCII
En ASCII : 22 caractères × 8 bits = 176 bits (22 octets).
Avec Shannon-Fano, on additionne pour chaque symbole « nombre d’occurrences × longueur du code » : i, u, c, ‘,’, p : 5 × 4 = 20 ; o, d : 2 × 5 = 10 ; n, j : 2 × 2 × 4 = 16 ; s : 3 × 3 = 9 ; _ : 4 × 3 = 12 ; e : 4 × 2 = 8, soit 75 bits, c’est-à-dire environ 10 octets.
75 bits au lieu de 176 : on utilise bien environ deux fois moins de place.
7. Arbre de codage du mot « chiffrer »
Occurrences : c, h, i, e : 1 ; f, r : 2 (total 8). Première séparation : c, h, i, e (4) et f, r (4), puis on recommence :

Partie C – Programmation Python
8. Fonction creer_dico_occ (lignes 8 et 10)
def creer_dico_occ(texte):
dico = {}
for symbole in texte:
if symbole in dico:
dico[symbole] = dico[symbole] + 1 # ligne 8
else:
dico[symbole] = 1 # ligne 10
return dico
9. Fonction somme_occ
def somme_occ(tab):
s = 0
for symbole, nb_occ in tab:
s = s + nb_occ
return s
10. Fonction shannon (lignes 9 et 11)
def shannon(symbole, tab):
if len(tab) == 1:
return ""
else:
t1, t2 = separe(tab)
if symbole in [elt[0] for elt in t1]:
return "1" + shannon(symbole, t1) # ligne 9
else:
return "0" + shannon(symbole, t2) # ligne 11
11. Terminaison de shannon
Le cas de base est un tableau d’un seul élément. À chaque appel récursif, tab est remplacé par t1 ou t2, qui sont strictement plus petits que tab (separe donne deux sous-tableaux non vides). La taille du tableau diminue donc jusqu’à 1 : la fonction termine.
12. Fonction encode_shannon
def encode_shannon(texte):
tab = creer_tab_trie(creer_dico_occ(texte))
code = ""
for symbole in texte:
code = code + shannon(symbole, tab)
return code
Une erreur, un oubli ? Écrivez-moi : frederic.peuriere@lfcl.pt
🔎 Exercices sur des thèmes similaires
-
Métropole 2025 – jour 1 – exercice 3
réseau, routage, arbres binaires de recherche, programmation — Difficulté : 🔥🔥🔥🔥🔥 -
Amérique du Nord 2025 – jour 2 – exercice 1
dictionnaires, arbres binaires, programmation, récursivité — Difficulté : 🔥🔥🔥🔥🔥 -
Centres étrangers 2023 – jour 2 – exercice 3
programmation, chaînes de caractères, arbres binaires de recherche, parcours de liste — Difficulté : 🔥🔥🔥🔥🔥 -
Nouvelle Caldédonie 2023 – jour 2 – exercice 2
programmation Python, récursivité — Difficulté : 🔥🔥🔥🔥🔥 -
Sujet Zéro 2023 – jour 1 – exercice 3
arbres binaires de recherche , POO — Difficulté : 🔥🔥🔥🔥🔥 -
Centres étrangers 2024 – jour 2 – exercice 2
POO, récursivité, arbres binaires, systèmes d'exploitation — Difficulté : 🔥🔥🔥🔥🔥