algorithmes

Algorithme de Boyer-Moore : recherche de motifs dans un texte

30 mars 2026 5 min de lecture

Introduction : Pourquoi un nouvel algorithme de recherche ?

Tu connais sûrement la méthode .find() en Python ou l'algorithme naïf qui compare le motif lettre par lettre à chaque position du texte. Ces méthodes fonctionnent, mais elles peuvent être très lentes sur de gros textes, comme un livre numérique ou une séquence ADN. Imagine devoir chercher un mot de 5 lettres dans un texte de 100 000 caractères... C'est là qu'intervient l'algorithme de Boyer-Moore, développé par Robert S. Boyer et J Strother Moore en 1977. Sa force ? Il est souvent sous-linéaire : il peut sauter des portions entières du texte, ce qui le rend extrêmement efficace en pratique. C'est un classique de l'informatique que tu dois maîtriser en NSI.

Le principe de base : lire de droite à gauche et sauter intelligemment

Contrairement à l'algorithme naïf qui lit de gauche à droite, Boyer-Moore compare le motif au texte en partant de la dernière lettre du motif. Cette inversion est la clé de sa performance. Prenons un exemple simple :

Texte : "UN ALGORITHME GENIAL"
Motif : "GENIE"

On aligne le début du motif avec le début du texte. On compare la dernière lettre du motif (E) avec le caractère correspondant dans le texte (U). Pas de correspondance. L'astuce : on regarde si ce caractère 'U' du texte apparaît quelque part dans notre motif "GENIE". La réponse est non. Dans ce cas, on peut faire glisser le motif complètement après ce 'U', car il est impossible qu'une correspondance existe si ce caractère n'est même pas dans le motif. On saute ainsi de plusieurs positions d'un coup ! Pour prendre ces décisions de saut, l'algorithme utilise deux heuristiques principales.

Les deux heuristiques magiques : Mauvais caractère et Bon suffixe

Ce sont les règles qui permettent de calculer de combien de positions on peut avancer sans risquer de rater une occurrence.

L'heuristique du Mauvais Caractère (Bad Character)

C'est celle que nous venons d'entrevoir. Lorsqu'une mauvaise correspondance (un "mauvais caractère") est trouvée :

  • On regarde ce caractère du texte qui ne correspond pas.
  • On cherche sa dernière occurrence dans le motif (en partant de la gauche).
  • On décale le motif pour aligner cette occurrence trouvée dans le motif avec le mauvais caractère du texte.
  • Si le caractère n'existe pas dans le motif, on décale le motif complètement après lui.

Cette recherche se fait en temps constant grâce à une table de pré-calcul (un dictionnaire en Python) créée avant la recherche.

L'heuristique du Bon Suffixe (Good Suffix)

Elle est utilisée quand une partie finale du motif (un suffixe) correspond au texte, mais que le caractère précédent dans le motif ne correspond pas. L'idée est de chercher une autre occurrence de ce suffixe qui correspond bien dans le motif, et de l'aligner. Si ce n'est pas possible, on décale le motif juste après la fin de la zone qui correspondait.

En pratique, pour chaque décalage, on prend le maximum des décalages proposés par les deux heuristiques. Cela garantit de ne jamais rater une occurrence potentielle tout en optimisant la vitesse.

Implémentation en Python pour la NSI

Voici une implémentation simplifiée qui utilise principalement l'heuristique du Mauvais Caractère, plus simple à coder et déjà très efficace.

def preprocess_bad_character(pattern):
    """Crée la table des derniers indices pour chaque caractère du motif."""
    bad_char = {}
    for i, char in enumerate(pattern):
        bad_char[char] = i  # Stocke la dernière occurrence
    return bad_char

def boyer_moore_search(text, pattern):
    """Recherche le motif dans le texte avec l'heuristique du mauvais caractère."""
    m = len(pattern)
    n = len(text)
    if m == 0:
        return 0
    
    bad_char = preprocess_bad_character(pattern)
    s = 0  # s est le décalage du motif par rapport au texte
    occurrences = []
    
    while s <= n - m:
        j = m - 1  # On commence par la fin du motif
        
        # Comparaison de droite à gauche
        while j >= 0 and pattern[j] == text[s + j]:
            j -= 1
        
        if j < 0:
            # Tout le motif correspond !
            occurrences.append(s)
            # Décalage pour chercher l'occurrence suivante
            s += (m - bad_char.get(text[s + m], -1)) if s + m < n else 1
        else:
            # Mauvais caractère trouvé à la position j
            bc_shift = j - bad_char.get(text[s + j], -1)
            s += max(1, bc_shift)  # On décale d'au moins 1
    
    return occurrences

# Exemple d'utilisation
texte = "abracadabra"
motif = "abra"
print("Occurrences trouvées aux indices :", boyer_moore_search(texte, motif))
# Affiche : [0, 7]

Complexité et applications réelles

Dans le pire des cas (par exemple, chercher "aaa" dans "aaaaaaaa"), la complexité est de O(n * m), comme l'algorithme naïf. Mais dans la pratique, sur des textes et motifs courants (langage naturel, code source), il est souvent en O(n/m) ou proche de O(n), ce qui est excellent. C'est pourquoi il est utilisé dans de nombreux outils :

  • Les commandes de recherche dans les fichiers (grep sous Linux).
  • Les moteurs de recherche dans les éditeurs de texte (Notepad++, VS Code).
  • Les logiciels de traitement de séquences biologiques (ADN, protéines).
  • Les systèmes de détection d'intrusion (recherche de signatures de virus).

Comprendre Boyer-Moore, c'est comprendre une idée fondamentale en algorithmique : pré-calculer des informations (les tables) pour accélérer considérablement la phase de recherche principale. C'est une stratégie que tu retrouveras dans bien d'autres algorithmes.

📚 Pour aller plus loin

Questions fréquentes

Pourquoi Boyer-Moore est-il plus rapide que la recherche naïve en pratique ?

Parce qu'il utilise des heuristiques (Mauvais Caractère et Bon Suffixe) pour sauter plusieurs caractères d'un coup au lieu de les examiner un par un. Il compare de droite à gauche et, en cas de non-correspondance, il peut déplacer le motif de plusieurs positions, parfois même de toute sa longueur, ce qui réduit énormément le nombre de comparaisons.

Dois-je connaître les deux heuristiques pour le bac de NSI ?

Le programme officiel mentionne l'algorithme de Boyer-Moore. Il est fortement conseillé de comprendre le principe général (recherche de droite à gauche, décalages intelligents) et au moins le fonctionnement détaillé de l'heuristique du Mauvais Caractère, qui est la plus intuitive. Connaître l'existence du Bon Suffixe montre une bonne compréhension de l'algorithme complet.

Quelle est la différence entre la table du 'Mauvais Caractère' et un simple test 'in' en Python ?

Un test `if caractere in motif:` vérifie juste la présence. La table du Mauvais Caractère va plus loin : elle stocke, pour chaque caractère présent, son *dernier indice* dans le motif. Cette information est cruciale pour calculer exactement de combien on peut décaler le motif pour réaligner une occurrence potentielle, et non pas juste sauter si le caractère est absent.

Peut-on utiliser Boyer-Moore pour rechercher des expressions régulières (regex) ?

Non, l'algorithme de Boyer-Moore est conçu pour la recherche d'un motif fixe (une chaîne de caractères exacte). Les expressions régulières, qui permettent des motifs flexibles (comme "a*b+"), nécessitent des algorithmes complètement différents, comme la construction d'un automate fini (NFA/DFA).

Bravo ! Tu as lu cet article
Inscris-toi pour sauvegarder ta progression et gagner des XP
Creer mon compte
Boyer-Moorerecherche textealgorithmemotifpython
Pixel