Pour chaque question, une seule réponse est correcte.
Question 1. L’algorithme naïf de recherche textuelle compare le motif de longueur $m$ dans un texte de longueur $n$. Sa complexité dans le pire cas est :
Correction publiée après la séance.
Question 2. L’algorithme de Boyer-Moore améliore la recherche en :
Correction publiée après la séance.
Question 3. Dans la table de décalages de Boyer-Moore-Horspool pour le motif "ABCD", quelle est la valeur associée à la lettre B ?
Correction publiée après la séance.
Question 4. On recherche le motif "abc" dans le texte "ababcabc". L’algorithme naïf trouve le motif aux positions :
Correction publiée après la séance.
Question 5. L’algorithme de Boyer-Moore est particulièrement efficace quand :
Correction publiée après la séance.
On considère texte = 'abracadabra' et motif = 'abr'.
i, les comparaisons effectuées et le résultat (« échec à j = ... » ou « trouvé ») :i |
Comparaisons | Résultat |
|---|---|---|
| 0 | ||
| 1 | ||
| … |
Pour chaque position i de 0 à len(texte) - len(motif), comparer texte[i + j] à motif[j] pour j = 0, 1, 2, en s’arrêtant à la première différence. Une ligne compte autant de comparaisons que de caractères examinés.
Combien de comparaisons au total l’algorithme naïf effectue-t-il ?
Additionner les comparaisons de toutes les lignes du tableau.
À quelles positions le motif est-il trouvé ?
Relever les lignes marquées « trouvé ».
Correction publiée après la séance.
Calculer la table de décalages pour le motif 'algorithme' (longueur 10).
Pour chaque caractère du motif sauf le dernier, le décalage vaut m - 1 - i, où i est la position de sa dernière apparition avant la fin du motif : un caractère présent plusieurs fois garde le plus petit décalage.
Quel est le décalage si le caractère du texte est 'x' (absent du motif) ?
Que fait l’algorithme du cours quand le caractère ne figure pas dans la table ?
Quel est le décalage si le caractère du texte est 'a' ?
Lire la valeur associée à 'a' dans la table de la question 1.
Quel est le décalage si le caractère du texte est 'e' (dernier caractère du motif, absent ailleurs) ?
Le dernier caractère du motif n’entre pas dans la table : 'e' est-il alors traité comme un caractère absent ?
Correction publiée après la séance.
On cherche le motif 'man' dans le texte 'le management est un art'.
Calculer la table de décalages du motif.
Même méthode qu’à l’exercice 2, avec m = 3.
Dérouler l’algorithme étape par étape en indiquant à chaque fois la position i, le caractère comparé, le décalage appliqué.
À chaque étape, comparer le motif au texte de droite à gauche, en partant de la position i + m - 1 ; en cas d’échec, lire le caractère du texte aligné avec la fin du motif et décaler du nombre donné par la table, ou de m s’il n’y figure pas.
Combien d’étapes sont nécessaires ? Combien l’algorithme naïf aurait-il testé de positions ?
L’algorithme naïf teste toutes les positions de 0 à n − m : compter n et m.
Correction publiée après la séance.
Modifier la fonction algo_naif pour qu’elle renvoie, en plus de la liste des indices, le nombre total de comparaisons effectuées.
Faire de même pour recherche_boyer_moore.
Comparer les deux compteurs pour la recherche de 'abd' dans 'abracadabra'.
Ajouter un compteur nb_comp, initialisé à 0 et augmenté de 1 juste avant chaque comparaison de caractères, puis le renvoyer avec la liste : return indices, nb_comp. Faire de même dans la boucle while de recherche_boyer_moore.
def algo_naif(texte, motif):
n = len(texte)
m = len(motif)
indices = []
nb_comp = 0
for i in range(n - m + 1):
trouve = True
for j in range(m):
nb_comp = ...
if texte[i + j] != motif[j]:
trouve = False
break
if trouve:
indices.append(i)
return indices, ...
Correction publiée après la séance.
timeitCréer une variable texte contenant un texte long (par exemple en lisant un fichier avec open('fichier.txt').read(), ou en utilisant texte = 'a' * 100000).
Choisir un motif de quelques caractères.
Utiliser le module timeit pour mesurer le temps d’exécution des deux algorithmes.
timeit.timeit(lambda: algo_naif(texte, motif), number=10) renvoie la durée totale de 10 exécutions, en secondes.
Tester avec un motif plus long (par exemple 10 caractères). Le rapport de vitesse change-t-il ?
Calculer, pour chaque motif, le quotient des deux durées, puis comparer ces quotients : Boyer-Moore-Horspool décale-t-il plus loin quand le motif est long ?
timeit (suite)Correction publiée après la séance.
Dans la version suivante de recherche_boyer_moore, la comparaison complète du motif est faite avec un slice Python (texte[i:i+m] == motif), ce qui est moins fidèle à l’esprit de l’algorithme.
# Version avec slice (à remplacer)
if texte[i + j] == motif[j]: # dernier caractère OK
if texte[i:i + m] == motif:
indices.append(i)
Réécrire cette partie avec une boucle while qui compare les caractères de droite à gauche, un par un, et qui s’arrête dès qu’un caractère ne correspond pas.
Partir de j = m - 1 et diminuer j tant que j >= 0 et que texte[i + j] == motif[j] : le motif est trouvé si j devient négatif.
Correction publiée après la séance.
Écrire des assertions pour tester les cas suivants, puis vérifier qu’elles passent pour les deux algorithmes :
'aa' dans 'aaaa').Chaque cas donne une ligne assert pour chacun des deux algorithmes, par exemple assert algo_naif("abc", "abc") == [0]. Pour les occurrences qui se chevauchent, compter à la main les positions de 'aa' dans 'aaaa'.
Correction publiée après la séance.
Construire un texte de longueur 1000 et un motif de longueur 10 qui provoquent le pire cas de l’algorithme naïf (un maximum de comparaisons).
Le pire cas survient quand, à chaque position, presque tous les caractères du motif correspondent avant l’échec : quel texte et quel motif, faits presque uniquement de la même lettre, produisent cela ?
Vérifier avec le compteur de comparaisons (exercice 4) que le nombre de comparaisons est bien proche de \(n \times m\).
Appeler la version avec compteur de l’exercice 4 sur ce texte et ce motif, et comparer le nombre obtenu à 1000 × 10.
Tester le même cas avec Boyer-Moore-Horspool. L’algorithme est-il plus rapide ici ?
Compter aussi les comparaisons de recherche_boyer_moore sur le même cas : de combien la table de décalages fait-elle avancer la fenêtre à chaque échec ?
Correction publiée après la séance.