Adloun

Corrigé CCINP 2026 Informatique MP — Problème 2 (I) (Q12 à Q24) : Ensembles de mots implémentés par tries

Sujet officiel du concours CCINP, session 2026, épreuve Informatique MP. Corrigé rédigé par Ibrahim Alame.

Sujet officiel (PDF, site du concours)

Énoncé

On veut représenter des ensembles de mots (correction orthographique, auto-complétion).

Q12. Citer deux structures au programme qui implémentent un dictionnaire.
Q13. Comment représenter un ensemble de mots par un dictionnaire pour tester l'appartenance ?

Un trie est un arbre dont chaque nœud porte un booléen et a un enfant par lettre (on ne dessine pas les enfants vides) ; le chemin de la racine à un nœud épelle un mot, qui appartient au trie si ce nœud porte true. Figure 1 : le trie de (« let » n'y est pas).

Q14. Dessiner le trie de .

La suite est en OCaml. Un mot est une liste de caractères ; s.[i] et String.length sont disponibles.

Q15. Écrire string_to_list : string -> char list, de coût linéaire justifié (expliquer toute fonction auxiliaire).

Les enfants d'un nœud sont stockés dans une liste de couples (lettre, sous-arbre) ; les arbres vides sont omis. La figure 2 et sa représentation :


type trie = Node of bool * (char * trie) list

Node (false,
   [('l',
     Node (false,
      [('e', Node (true, [('s', Node (true, []))])); ('a', Node (true, []))]))])

Q16. empty_trie : unit -> trie, le trie vide ayant le moins de nœuds.
Q17. max_list : int list -> int, récursive, liste non vide.
Q18. list_map : ('a -> 'b) -> 'a list -> 'b list, récursive, sans List.map.
Q19. height : trie -> int (hauteur).
Q20. size : trie -> int (nombre de nœuds).
Q21. Que calcule la fonction suivante ? Pourquoi ?


let rec f t =
  match t with
  |Node (true, []) -> 1
  |Node (false, []) -> 0
  |Node (b, (letter,child)::tail) -> (f child) + (f (Node (b, tail)))

Q22. is_in_trie : char list -> trie -> bool (appartenance d'un mot).
Q23. add_to_trie : char list -> trie -> trie (ajout d'un mot).
Q24. Sur le trie de Q14, quel problème de taille et de redondance apparaît ?

Corrigé

Q12. Les tables de hachage (c'est l'implémentation du dict de Python) et les arbres binaires de recherche, équilibrés de préférence (AVL, arbres rouge-noir), qui garantissent un coût logarithmique par opération.

Q13. On prend pour clés les mots de l'ensemble, associés à une valeur sans importance (True, ou () en OCaml). Tester si un mot appartient à l'ensemble revient à tester si est une clé du dictionnaire (m in d en Python), ce qui coûte en moyenne accès à une table de hachage (plus le calcul du haché de , en ), ou comparaisons de mots dans un arbre binaire de recherche équilibré contenant mots. En Python, c'est exactement ce qu'offre le type set, un dictionnaire sans valeurs.

Q14. Les mots commençant par la même lettre partagent leur branche ; on obtient 25 nœuds pour 7 mots.

Les nœuds true sont ceux de « en », « bot » (nœuds internes) et des cinq feuilles.

Q15. On construit la liste de la fin vers le début, pour n'utiliser que des ajouts en tête.


let string_to_list s =
  (* aux i acc : la liste des caractères s.[0..i], suivie de acc *)
  let rec aux i acc =
    if i < 0 then acc else aux (i - 1) (s.[i] :: acc)
  in
  aux (String.length s - 1) []

La fonction auxiliaire aux i acc renvoie [s.[0]; …; s.[i]] @ acc : c'est vrai pour , et si c'est vrai au rang , l'appel aux (i-1) (s.[i] :: acc) renvoie [s.[0]; …; s.[i-1]] @ (s.[i] :: acc), ce qu'on voulait. Avec et acc = [], on obtient la liste de tous les caractères. Le paramètre décroît strictement jusqu'à : il y a appels, chacun en temps constant (accès s.[i] et « cons » en ), d'où un coût ; la récursion est terminale. Essais : string_to_list "lettre" donne ['l'; 'e'; 't'; 't'; 'r'; 'e'], et "" donne [].

Q16. Le trie de l'ensemble vide réduit à un seul nœud, sa racine, qui ne porte aucun mot :


let empty_trie () = Node (false, [])

On ne peut pas faire moins : le type trie n'a pas de constructeur d'arbre vide, tout trie a au moins une racine.

Q17.


let rec max_list lst =
  match lst with
  | [] -> failwith "max_list : liste vide"
  | [x] -> x
  | x :: q -> let m = max_list q in if x >= m then x else m

Par récurrence sur la longueur : un singleton a pour maximum son unique élément ; sinon le maximum de x :: q est le plus grand de x et du maximum de q (non vide). Un appel par élément : coût linéaire. Essais : max_list [3; 7; 2] = 7, max_list [-3; -1; -8] = -1.

100 % gratuit

La suite du corrigé est sur Adloun

Le corrigé rédigé en entier, question par question, et le tuteur pour poser des questions sur ce sujet.

Voir le corrigé complet, gratuitement

Inscription gratuite en 30 secondes (e-mail, nom d'utilisateur, mot de passe, classe ou profil), sans carte bancaire : arrivée directe sur le corrigé.

Toutes les parties de l'épreuve

Corrigé complet gratuit →