Algorithme de Boyer-Moore-Horspool

From Wikipedia, the free encyclopedia

Illustration de la recherche de la sous-chaîne "long des" dans la première strophe du poème Chanson d'automne de Paul Verlaine.

L'algorithme de Boyer-Moore-Horspool, parfois appelé algorithme de Horspool[1] est un algorithme de recherche de sous-chaîne publié par Nigel Horspool en 1980[2]. Il consiste en une simplification de l’algorithme de Boyer-Moore qui ne garde que la première table de saut. On considère un texte et on note m le motif (la sous-chaîne) à chercher dans ce texte.

Rappel de l'algorithme naïf

Expliquons le principe sur la recherche du motif m string dans le texte wikipedia. L'algorithme de Boyer-Moore-Horspool est une adaptation de l'algorithme naïf pour rechercher une sous-chaîne. L'algorithme utilise un pré-traitement du motif afin de calculer le saut maximum à effectuer après avoir trouvé une non-concordance. Durant la recherche la comparaison se fait de la droite vers la gauche.

On considère le motif comme une fenêtre glissante sur le texte. On commence avec :

wikipedia
string

Dans l'algorithme naïf (voir l'article algorithme de recherche de sous-chaîne), on compare wikipe et string, constatant qu'ils ont différents, on décale le motif d'une case vers la droite :

wikipedia
 string

Mais on voit que tous ces décalages mèneront à un échec :

wikipedia
 string
  string
   string

Amélioration

Dans l'algorithme de Boyer-Moore-Horspool, la comparaison du motif avec la portion du texte correspondante s'effectue de droite à gauche. Ainsi à la première étape, le dernier caractère du motif est comparé à sa position dans le texte, à savoir g et e.

wikipedia
string

Ces deux caractères étant différents, on cherche donc à savoir de combien il faut décaler le texte. Comme e n'apparaît pas dans le motif, il faut complètement décaler le motif, soit de 6. Mais alors, le motif déborde du texte :

wikipedia
      string

L'algorithme termine en déclarant que string n'apparaît pas dans wikipedia. Cet exemple extrême est intéressant car un seul caractère du texte a été lu.

Idée

Dans l'exemple précédent, le caractère e n'apparaît pas dans le motif. Si jamais la lettre apparaît dans le motif, il faut savoir de combien il faut décaler. L'algorithme précalcule une table de la dernière occurrence[3], qui indique pour chaque lettre de combien il faut décaler.

Pseudo-code

Dans cette section, on suppose que les indices dans le texte et motif commence à 0. L'algorithme commence par précalculer[3] une table T. Puis l'algorithme est similaire à l'algorithme naïf sauf que l'on décale de T[texte[j]] au lieu de décaler de 1, où j est l'indice dans le texte, aligné avec le dernier caractère de la fenêtre glissante :

                                          j
                                          ↓
texte :       texte très long dans lequel on effectue une recherche d'un motif
motif :                               motif

Dans cette section, on suppose que les indices dans le texte et motif commence à 0.

Construction de la table de la dernière occurrence

L'algorithme commence par précalculer la table T de la dernière occurrence[3]. Crochemore et al. définissent la table T comme suit. Pour toute lettre a, . Autrement dit, si la lettre a n'apparaît pas dans le motif, alors T[a] vaut |m|. Sinon, on considère la position k de la dernière occurrence de a dans le motif m : T[a] est alors |m| - 1 - k. Beauquier, Berstel et Chrétienne[4] proposent une définition équivalente et l'appelle fonction de la dernière occurrence :

.


La construction de cette table est donnée par :

fonction constructionTable(m)
        T := une table indexée par les lettres      
        pour toute lettre a
                T[a] := |m|
        pour k = 0 à |m| - 2
                T[m[k]] := |m| - 1 - k
        renvoyer T   

Fonction principale

Puis voici le pseudo-code[3] de l'algorithme à proprement parler.

fonction rechercher(m, texte)
       T := constructionTable(m)
       j := |m| - 1
       tant que j < |texte|
             signaler si texte[j - (|m|-1) .. j] = m
             j := j + T[texte[j]]

L'algorithme est similaire à l'algorithme naïf sauf que l'on décale de T[texte[j]] au lieu de décaler de 1, où j est l'indice dans le texte, aligné avec le dernier caractère de la fenêtre glissante.

Exemples

Cas où texte[j] est dans le motif

Voici un exemple d'alignement :

                                          j
                                          ↓
texte :       texte très long dans lequel on effectue une recherche d'un motif
motif :                               motif

La définition de la table T revient donc à considérer la dernière occurrence de la lettre à la position j (ici la lettre o) dans le mot motif, puis à aligner cette dernière occurrence avec l'actuel o dans le texte. Après l'affectation j := j + T[texte[j]], on obtient :

                                             j
                                             ↓
texte :       texte très long dans lequel on effectue une recherche d'un motif
motif :                                  motif

Cas où texte[j] n'est pas dans le motif

Voici un exemple d'alignement où la lettre sous le curseur dans le texte n'apparaît pas dans le motif (u n'apparaît pas dans le mot motif) :

                                                   j
                                                   ↓
texte :       texte très long dans lequel on effectue une recherche d'un motif
motif :                                        motif

Dans ce cas, T[texte[j]] = |m|. Dans l'exemple, on décale donc de |m| = 5 :

                                                        j
                                                        ↓
texte :       texte très long dans lequel on effectue une recherche d'un motif
motif :                                             motif

Complexité

Implémentation

Références

Related Articles

Wikiwand AI