<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
  <category>
    <text>$course$/QCM de NSI/Terminale/Recherche textuelle</text>
  </category>
  <info format="html">
    <text><![CDATA[<p>Recherche d'un motif dans un texte, algorithme naïf (force<br/>
brute), algorithme de Boyer-Moore-Horspool (comparaison de<br/>
droite à gauche, table de décalages), pré-traitement,<br/>
complexités, applications (grep, Ctrl+F, ADN).</p>]]></text>
  </info>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q01 : Position du problème</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>En quoi consiste la <strong>recherche textuelle</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La recherche textuelle est un problème fondamental en<br/>
informatique : elle est utilisée des milliards de fois<br/>
par jour (recherche web, éditeurs de texte, analyse de<br/>
données massives).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Chercher un mot dans un dictionnaire trié</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est un cas particulier qui se résout par<br/>
recherche dichotomique. La recherche textuelle est<br/>
plus générale.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Compter le nombre de caractères dans un texte</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce n'est pas une recherche, juste un<br/>
comptage trivial.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Trier entièrement un texte par ordre alphabétique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport avec le tri.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Trouver toutes les positions d'un motif dans un texte</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est exactement le problème étudié.<br/>
Applications : Ctrl+F dans un éditeur, <code>grep</code>,<br/>
analyse de séquences ADN, moteurs de recherche.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q02 : Principe de l'algorithme naïf</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel est le principe de l'<strong>algorithme naïf</strong> (force brute) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'algorithme naïf est simple mais inefficace : il<br/>
avance toujours d'une seule position après chaque<br/>
échec, même quand le premier caractère ne correspondait<br/>
pas.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>On compare depuis la fin du motif et on saute plusieurs positions</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est l'idée de l'algorithme de Boyer-Moore. L'algorithme naïf compare de gauche à droite et n'avance que d'une position après chaque échec.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>On teste chaque position de départ et on compare caractère par caractère</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : pour chaque indice <code>i</code> de 0 à<br/>
<code>n - m</code>, on compare le motif au texte à partir de<br/>
la position <code>i</code>. Dès qu'un caractère diffère, on<br/>
passe à la position suivante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>On découpe le texte en deux et on cherche dans chaque moitié</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait du « diviser pour régner », ce<br/>
que ne fait pas l'algorithme naïf.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>On compare le motif uniquement à la fin du texte</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on teste <strong>toutes</strong> les positions, pas<br/>
seulement la fin.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q03 : Borne de la boucle</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans l'algorithme naïf, la boucle externe va de 0 à<br/>
quelle valeur (incluse) pour pouvoir aligner un motif<br/>
de longueur <code>m</code> dans un texte de longueur <code>n</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Erreur classique : oublier le <code>+1</code> dans <code>range</code>. Pour<br/>
éviter ce piège, vérifier sur un petit exemple :<br/>
<code>texte = "abc"</code>, <code>motif = "bc"</code>, longueurs <code>n=3</code>,<br/>
<code>m=2</code>. Positions valides : 0, 1. Donc <code>range(2)</code> =<br/>
<code>range(n - m + 1)</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>n - 1</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on dépasserait la fin du texte. À la<br/>
position <code>n - 1</code>, il ne reste qu'un caractère pour<br/>
aligner les <code>m</code> caractères du motif.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>n - m - 1</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on raterait la dernière position valide<br/>
(le motif placé à la toute fin du texte).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>n</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la position <code>n</code> n'existe même pas dans le<br/>
texte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>n - m</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est la dernière position où le<br/>
motif tient encore dans le texte. En Python, on<br/>
écrit donc <code>range(n - m + 1)</code> (la borne supérieure<br/>
de <code>range</code> étant exclusive).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q04 : Complexité du naïf</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la complexité dans le <strong>pire cas</strong> de<br/>
l'algorithme naïf de recherche textuelle ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le pire cas se rencontre par exemple avec un texte<br/>
<code>"aaaa...a"</code> et un motif <code>"aaab"</code> : à chaque position,<br/>
les m-1 premiers caractères correspondent avant<br/>
l'échec, soit ~ n × m comparaisons.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n + m)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un coût en O(n + m) supposerait de ne jamais revenir sur les caractères déjà comparés. L'algorithme naïf peut refaire jusqu'à m comparaisons à chacune des positions du texte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>O(n × m)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la boucle externe parcourt environ<br/>
n positions ; pour chacune, on peut faire jusqu'à<br/>
m comparaisons. D'où O(n × m), souvent noté<br/>
O(n²) quand n ≫ m.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(log n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune dichotomie dans cet algorithme.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : O(n) supposerait une seule comparaison<br/>
par position, ce qui n'est pas le cas dans le<br/>
pire cas.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q05 : Idée clé de Boyer-Moore</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est l'<strong>idée centrale</strong> de l'algorithme de<br/>
Boyer-Moore-Horspool ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Comparer de droite à gauche peut sembler contre-intuitif,<br/>
mais c'est précisément ce qui permet de tirer parti des<br/>
caractères « rares » dans le motif pour faire de grands<br/>
sauts.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Comparer le motif de gauche à droite mais en sautant les voyelles</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun rapport avec les voyelles. La<br/>
comparaison va de droite à gauche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Utiliser la programmation dynamique avec une mémoïsation complète</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Boyer-Moore n'utilise pas de mémoïsation.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pré-trier le texte pour faire une recherche dichotomique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on ne peut pas trier un texte sans<br/>
détruire sa structure. La recherche dichotomique<br/>
ne s'applique pas ici.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Comparer le motif de droite à gauche et sauter en cas d'échec via une table de décalages</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : ces deux idées combinées<br/>
permettent d'éviter de comparer chaque caractère<br/>
du texte. Dans le meilleur cas, on saute m<br/>
positions à chaque fois.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q06 : Applications concrètes</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Lequel des outils suivants utilise une variante de la<br/>
recherche textuelle (algorithme naïf ou Boyer-Moore) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La recherche textuelle est l'une des opérations les plus exécutées en informatique. Les implémentations réelles utilisent souvent Boyer-Moore ou des variantes de cet algorithme.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La commande Unix <code>grep</code>, et aucun autre outil</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p><code>grep</code> utilise bien la recherche textuelle, mais ce<br/>
n'est pas le <strong>seul</strong> outil concerné : Ctrl+F et<br/>
l'analyse de séquences ADN aussi.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>grep</code>, Ctrl+F et l'analyse de séquences ADN</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : Ctrl+F, <code>grep</code> et la bio-informatique<br/>
sont trois applications classiques, qui reposent<br/>
toutes sur la recherche d'un motif dans un texte. La<br/>
recherche textuelle est partout.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La fonction Ctrl+F d'un éditeur de texte, et elle seule</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Ctrl+F utilise bien la recherche textuelle, mais ce<br/>
n'est pas la <strong>seule</strong> application : <code>grep</code> et<br/>
l'analyse de séquences ADN aussi. Lis bien toutes les<br/>
propositions.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'analyse de séquences ADN exclusivement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'analyse de séquences ADN utilise bien la recherche<br/>
textuelle, mais ce n'est pas la <strong>seule</strong> application :<br/>
<code>grep</code> et Ctrl+F aussi.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q07 : Que renvoie l'algorithme ?</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Lorsqu'on programme <code>recherche(texte, motif)</code>, quel<br/>
est le retour le plus utile ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Renvoyer la liste des positions est la convention<br/>
standard. La méthode Python <code>str.find()</code> renvoie<br/>
l'indice de la première occurrence (ou -1) ; pour<br/>
toutes les occurrences, il faut écrire sa propre<br/>
fonction ou utiliser <code>re.finditer</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un booléen <code>True</code>/<code>False</code> indiquant la présence</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Insuffisant : on ne sait pas <strong>où</strong> est le motif,<br/>
ni combien de fois il apparaît.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La liste des indices de début de chaque occurrence</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est l'information la plus riche<br/>
(<code>[]</code> si absent, <code>[3, 7]</code> si présent aux<br/>
positions 3 et 7). Un booléen ou un compte<br/>
peuvent en être déduits.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le texte modifié pour retirer le motif</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait un <code>replace</code>, pas une recherche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La longueur du motif</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est connu d'avance via <code>len(motif)</code>,<br/>
aucun intérêt à la renvoyer.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q08 : Trace de l'algorithme naïf</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Avec l'algorithme naïf, on cherche <code>motif = "ab"</code> dans<br/>
<code>texte = "babab"</code>. Quel est le résultat ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour vérifier rapidement, surligne les caractères du<br/>
texte un par un et identifie les <code>"ab"</code> consécutifs.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[0, 2]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : à la position 0, on a <code>"b"</code> ≠ <code>"a"</code>,<br/>
donc échec immédiat. Le motif ne commence pas en 0.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>[1, 3]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : positions 1 (<code>"ab"</code>) et 3 (<code>"ab"</code>).<br/>
Aux positions 0, 2, 4 le premier caractère est<br/>
<code>"b"</code>, ce qui échoue.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le motif <code>"ab"</code> apparaît bien dans<br/>
<code>"babab"</code> (deux fois).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[1, 2, 3]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : à la position 2, le caractère est <code>"b"</code>,<br/>
donc échec immédiat (<code>"b"</code> ≠ <code>"a"</code>).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q09 : Pire cas du naïf</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Lequel de ces couples (texte, motif) constitue un<br/>
<strong>pire cas</strong> pour l'algorithme naïf ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le pire cas se rencontre quand le motif et le texte<br/>
partagent un long préfixe commun à chaque position<br/>
(ex. : alphabets très réduits, motifs « presque<br/>
identiques » au texte).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>texte = <code>'hello'</code>, motif = <code>'hello'</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce cas se résout en m comparaisons à la<br/>
position 0. Pas de pire cas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>texte = <code>'aaaaaaaaa'</code>, motif = <code>'aaab'</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : à chaque position, les 3 premiers<br/>
caractères correspondent avant l'échec sur le<br/>
dernier. On effectue ~ 4 × n comparaisons.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>texte = <code>'abracadabra'</code>, motif = <code>'xyz'</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Au contraire : <code>'x'</code> n'apparaît jamais dans le<br/>
texte, donc l'échec est immédiat (1 comparaison<br/>
par position). C'est un <strong>bon</strong> cas pour le naïf.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>texte = <code>'a'</code>, motif = <code>'ab'</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>m &gt; n</code>, la boucle ne s'exécute même pas.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q10 : Direction de comparaison</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans Boyer-Moore-Horspool, par quel caractère du motif<br/>
commence-t-on la comparaison ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Comparer de droite à gauche est la clé : si le<br/>
caractère du texte aligné avec la fin du motif n'est<br/>
pas dans le motif, on peut sauter de m positions sans<br/>
risque.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le premier (gauche)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait l'algorithme naïf. Boyer-Moore<br/>
fait l'inverse.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Le dernier (droite)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on aligne le motif sur le texte<br/>
puis on compare d'abord <code>motif[m-1]</code> avec<br/>
<code>texte[i + m - 1]</code>. C'est ce caractère qui décide<br/>
du décalage à appliquer en cas d'échec.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un caractère choisi au hasard</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la recherche serait non déterministe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le caractère du milieu</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun algorithme classique ne fait cela.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q11 : Construction de la table</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour le motif <code>"dab"</code> (longueur 3), quelle est la table<br/>
de décalages de Boyer-Moore-Horspool ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Formule : pour le caractère c en position i (la plus<br/>
à droite, hors dernière position), décalage = m - 1 - i.<br/>
Caractères absents du motif : décalage = m.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>{'d': 3, 'a': 3, 'b': 3}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la valeur 3 (= m) correspond aux<br/>
caractères <strong>absents</strong> du motif.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>{'d': 2, 'a': 1}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : pour <code>'d'</code> en position 0, décalage = 3 - 1 - 0 = 2 ; pour <code>'a'</code> en position 1, décalage = 3 - 1 - 1 = 1. Le <code>'b'</code><br/>
final est exclu.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>{'d': 0, 'a': 1, 'b': 2}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce sont les positions, pas les décalages, et il ne faut pas<br/>
inclure <code>'b'</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>{'d': 2, 'a': 1, 'b': 0}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on <strong>n'inclut pas</strong> le dernier caractère<br/>
(<code>'b'</code>) dans la table, sinon on risque un<br/>
décalage de 0 qui ferait boucler l'algorithme.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q12 : Caractère absent du motif</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Avec le motif <code>"dab"</code> (longueur 3), le caractère du<br/>
texte aligné avec la fin du motif est <code>'z'</code>. Quel<br/>
décalage applique-t-on ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>C'est le « cadeau » de Boyer-Moore : un grand alphabet<br/>
(lettres, chiffres, ponctuation) signifie beaucoup de<br/>
caractères absents du motif, donc des sauts maximaux.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>1</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le décalage <strong>par défaut</strong> de<br/>
l'algorithme naïf, mais Boyer-Moore fait mieux.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>3</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>'z'</code> n'apparaît pas dans <code>"dab"</code>,<br/>
on peut donc sauter de toute la longueur du<br/>
motif (3) sans risquer de manquer une occurrence.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>0</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un décalage de 0 ferait boucler<br/>
l'algorithme indéfiniment.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>2</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : 2 est le décalage pour <code>'d'</code>, pas pour<br/>
un caractère absent.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q13 : Caractère répété</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour le motif <code>"maman"</code> (longueur 5), quelle est la<br/>
table de décalages ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Quand un caractère apparaît plusieurs fois dans le<br/>
motif, on garde la dernière occurrence (avant la fin)<br/>
car elle donne le <strong>plus petit</strong> décalage sûr.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>{'m': 4, 'a': 3}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>'m'</code> apparaît plusieurs fois, on<br/>
ne garde que la position <strong>la plus à droite</strong><br/>
(hors dernière position), ici 2.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>{'m': 2, 'a': 3}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce sont les positions des caractères, pas les<br/>
décalages ; le décalage vaut 5 - 1 - position.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>{'m': 2, 'a': 1}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>'m'</code> en position 2, décalage 5 - 1 - 2 = 2 ; <code>'a'</code> en position 3, décalage 5 - 1 - 3 = 1.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>{'m': 2, 'a': 1, 'n': 0}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on <strong>n'inclut pas</strong> le dernier caractère<br/>
(<code>'n'</code>).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q14 : Pourquoi exclure le dernier caractère ?</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi exclut-on le dernier caractère du motif lors<br/>
du pré-traitement ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>C'est un point subtil mais essentiel. Sans cette<br/>
exclusion, l'algorithme entrerait dans une boucle<br/>
infinie dès qu'on rencontre un caractère identique au<br/>
dernier du motif.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parce qu'un décalage de 0 ferait boucler l'algorithme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : en cas d'égalité avec le dernier<br/>
caractère du motif, on veut chercher la<br/>
précédente occurrence (à gauche), ou décaler de<br/>
m s'il n'y en a pas. Décaler de 0 ferait revenir<br/>
à la même position et boucler.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour économiser une quantité notable de mémoire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le gain mémoire est négligeable. La<br/>
vraie raison est algorithmique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'il est toujours absent du motif</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il fait évidemment partie du motif<br/>
(puisqu'il en est le dernier caractère).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que Python ne permet pas d'indexer la dernière position</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Python le permet sans problème.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q15 : Trace de Boyer-Moore</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On cherche <code>motif = "dab"</code> dans <code>texte = "abracadabra"</code>.<br/>
Au premier alignement (i=0), on compare <code>texte[2]</code><br/>
(<code>'r'</code>) avec <code>motif[2]</code> (<code>'b'</code>). Échec. Sachant que<br/>
<code>'r'</code> n'est pas dans le motif, de combien décale-t-on ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>C'est précisément ce type de saut qui fait la<br/>
puissance de Boyer-Moore : sur du texte naturel<br/>
(alphabet riche), de tels sauts maximaux sont<br/>
fréquents.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>11 (la longueur du texte)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on n'a aucune raison de sauter à la fin<br/>
du texte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>2</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : 2 est le décalage de <code>'d'</code>, pas d'un<br/>
caractère absent.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>1</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait l'algorithme naïf. Boyer-Moore<br/>
tire parti de l'absence de <code>'r'</code> dans le motif.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>3 (la longueur du motif)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>'r'</code> est absent de <code>"dab"</code>, on<br/>
saute de m = 3 positions. La nouvelle position<br/>
devient i = 3.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q16 : Prétraiter le motif plutôt que le texte</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Avant de parcourir le texte, l'algorithme de Boyer-Moore calcule une table de décalages. Pourquoi ce prétraitement porte-t-il sur le <strong>motif</strong> et non sur le texte ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La table indique, pour chaque caractère, de combien décaler le motif lorsque ce caractère se trouve en face de la dernière position du motif. Elle ne dépend que du motif : on la calcule une seule fois, et on peut même la réutiliser pour chercher le même motif dans plusieurs textes.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Le motif est court et connu d'avance : sa table sert à chaque échec</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la table se calcule en un seul passage sur les m caractères du motif, puis elle est consultée à chaque échec, quelle que soit la longueur du texte parcouru.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le texte ne peut pas être lu avant la recherche proprement dite</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : rien n'empêche de lire le texte à l'avance. Mais le préparer demanderait de le parcourir en entier, ce que la recherche cherche justement à éviter.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La table du texte serait identique à celle du motif</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le texte contient en général d'autres caractères, à d'autres positions, que le motif. Une table construite sur le texte n'aurait rien à voir avec celle du motif.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le motif est modifié pendant la recherche et doit donc être préparé</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le motif n'est jamais modifié pendant la recherche. La table est seulement lue pour savoir de combien décaler le motif.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q17 : Table produite par le code du prétraitement</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On considère la fonction suivante, qui construit la table de décalages de Boyer-Moore-Horspool :<br/>
<pre><code>def table_decalages(motif):
    m = len(motif)
    table = {}
    for i in range(m - 1):
        table[motif[i]] = m - 1 - i
    return table
print(table_decalages("RIRE"))</code></pre><br/>
Qu'affiche ce programme ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La table associe à chaque caractère du motif, sauf le dernier, sa distance à la fin du motif. Quand un caractère apparaît plusieurs fois, la dernière affectation l'emporte : on garde le plus petit décalage, le seul qui ne risque pas de faire manquer une occurrence.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>{'R': 3, 'I': 2}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tu gardes la valeur de la première apparition de <code>R</code>. La boucle rencontre <code>R</code> une seconde fois, à l'indice 2, et l'affectation <code>table['R'] = 1</code> remplace l'ancienne valeur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>{'R': 1, 'I': 2}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : avec m = 4, l’indice 0 associe <code>R</code> à 3, l’indice 1 associe <code>I</code> à 2, l’indice 2 associe <code>R</code> à 1 ; la dernière affectation pour <code>R</code> remplace la valeur 3.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>{'R': 1, 'I': 2, 'E': 0}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la boucle <code>for i in range(m - 1)</code> s'arrête à l'indice 2. Le dernier caractère, <code>E</code>, n'est jamais traité.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>{'R': 2, 'I': 1}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tu ranges l'indice <code>i</code> au lieu de <code>m - 1 - i</code>. La valeur stockée est la distance entre le caractère et la dernière position du motif.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q18 : Quand BM n'apporte rien</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans quel cas Boyer-Moore-Horspool n'apporte-t-il<br/>
<strong>aucun gain</strong> par rapport à l'algorithme naïf ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Règle empirique : Boyer-Moore est efficace si motif<br/>
long + alphabet varié. Les pires cas se rencontrent<br/>
avec des séquences quasi-uniformes (séquences ADN<br/>
avec un seul nucléotide, par exemple).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Quand l'alphabet utilisé est particulièrement large</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le cas <strong>favorable</strong> à<br/>
Boyer-Moore (sauts maximaux fréquents).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Quand texte et motif sont presque uniformes (que des <code>'a'</code>)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : quand texte et motif n'ont presque<br/>
que des caractères identiques, l'alphabet utile est<br/>
réduit, les décalages sont presque toujours de 1 et<br/>
on retombe sur un parcours position par position.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Quand le motif cherché est court (trois ou quatre caractères)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Partiellement vrai : les sauts sont limités à m,<br/>
donc le gain est modeste, mais il existe. Ce n'est<br/>
pas le <strong>pire cas</strong>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Quand le texte parcouru est très long (plusieurs mégaoctets)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : au contraire, plus le texte est long,<br/>
plus l'écart en valeur absolue grandit.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q19 : Majuscules et minuscules dans la recherche</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La fonction <code>recherche_naif(texte, motif)</code> renvoie la liste des indices où le motif apparaît, en comparant les caractères un à un avec <code>==</code>. Que renvoie l'appel <code>recherche_naif("Le Chat dort", "chat")</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La recherche textuelle compare des caractères, et une majuscule n'est pas le même caractère que la minuscule correspondante. Pour trouver <code>"Chat"</code> quelle que soit son écriture, on peut convertir le texte et le motif avec <code>lower()</code> avant la recherche.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[3]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>"Chat"</code> commence bien à l'indice 3, mais <code>C</code> et <code>c</code> sont deux caractères différents, de codes 67 et 99. La comparaison échoue dès le premier caractère du motif.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>[]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la comparaison <code>==</code> distingue <code>C</code> (code 67) de <code>c</code> (code 99). Aucune position du texte ne correspond entièrement au motif <code>"chat"</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>[4]</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tu numérotes les caractères à partir de 1 et tu négliges la différence entre majuscule et minuscule. En réalité, aucune position ne convient.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur, car le texte contient des espaces</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'espace est un caractère comme un autre. Il est simplement comparé aux caractères du motif, sans provoquer d'erreur.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q20 : Un motif plus long, moins d'alignements</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un texte de 60 caractères ne contient que des points. On y cherche avec Boyer-Moore-Horspool d'abord le motif <code>"abc"</code>, puis le motif <code>"abcdef"</code>. Combien d'alignements l'algorithme examine-t-il dans chacun des deux cas ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le point est absent des deux motifs : à chaque alignement, la première comparaison échoue et le motif saute de toute sa longueur. Plus le motif est long, plus les sauts sont grands, et moins l'algorithme examine d'alignements.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>58 puis 55</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : 58 et 55 sont les nombres de positions testées par l'algorithme naïf, qui avance d'une seule position à chaque échec. Boyer-Moore saute bien plus loin.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>20 puis 40</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : tu penses qu'un motif plus long demande plus d'alignements. C'est l'inverse : le point étant absent du motif, chaque échec fait sauter le motif de toute sa longueur, donc de 6 pour <code>"abcdef"</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>20 puis 10</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : avec <code>"abc"</code>, les alignements sont 0, 3, 6, …, 57, soit 20 ; avec <code>"abcdef"</code>, ce sont 0, 6, 12, …, 54, soit 10.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>60 puis 60</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'algorithme ne s'aligne pas sur chaque caractère du texte. Chaque échec provoque un saut de toute la longueur du motif, puisque le point en est absent.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q21 : Nombre d'alignements de BM</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On cherche <code>motif = "dab"</code> (longueur 3) dans<br/>
<code>texte = "abracadabra"</code> (longueur 11) avec<br/>
Boyer-Moore-Horspool. Combien d'alignements distincts<br/>
du motif sont effectués (i.e. valeurs successives de<br/>
<code>i</code>) avant la fin de l'algorithme ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Trace complète : i=0, échec sur 'r' (saute 3) ; i=3,<br/>
échec sur 'a' (saute 1) ; i=4, échec sur 'd' (saute<br/>
2) ; i=6, succès. Quatre alignements pour 9 dans le<br/>
naïf : économie de plus de la moitié.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>11</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on ne teste pas chaque position du<br/>
texte (c'est tout l'intérêt de Boyer-Moore).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>2</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : trop peu, on doit bien tester plusieurs<br/>
positions intermédiaires.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>9 (comme l'algorithme naïf)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Boyer-Moore fait moins d'alignements<br/>
grâce aux sauts.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>4</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : i = 0 → saute de 3 → i = 3 →<br/>
saute de 1 → i = 4 → saute de 2 → i = 6 (motif<br/>
trouvé) → i = 7 → fin. Soit 4 alignements<br/>
distincts (0, 3, 4, 6) avant détection.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q22 : Table d'un motif complexe</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la table de décalages de<br/>
Boyer-Moore-Horspool pour le motif <code>"abracadabra"</code><br/>
(longueur 11) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Méthode systématique : balayer le motif de droite à<br/>
gauche en s'arrêtant <strong>avant</strong> le dernier caractère.<br/>
Pour chaque nouveau caractère rencontré, calculer<br/>
m - 1 - i.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>{'a': 10, 'b': 9, 'r': 8, 'c': 6, 'd': 4}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce sont les décalages calculés sur la<br/>
<strong>première</strong> position de chaque caractère. Il faut<br/>
prendre la dernière position (hors fin).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>{'a': 3, 'b': 2, 'r': 1, 'c': 6, 'd': 4}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse. Dernière position (hors fin) de<br/>
chaque caractère : a en 7 → 11-1-7=3 ; b en 8 → 11-1-8=2 ; r en 9 → 11-1-9=1 ; c en 4 → 11-1-4=6 ; d en 6 → 11-1-6=4. Le <code>'a'</code> final est exclu.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>{'a': 7, 'b': 8, 'r': 9, 'c': 4, 'd': 6}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce sont les positions, pas les<br/>
décalages. Le décalage est m - 1 - position.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>{'a': 0, 'b': 2, 'r': 1, 'c': 6, 'd': 4}</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le <code>'a'</code> final est <strong>exclu</strong> ; sa dernière<br/>
position retenue est celle qui précède la fin du motif.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q23 : Le texte qui ralentit Boyer-Moore</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On cherche le motif <code>"ABCD"</code> avec Boyer-Moore-Horspool dans un texte formé de 20 fois la même lettre. Pour lequel des textes suivants l'algorithme examine-t-il <strong>le plus</strong> d'alignements ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour <code>"ABCD"</code>, la table associe <code>A</code> à 3, <code>B</code> à 2, <code>C</code> à 1, et tout autre caractère à 4. À chaque alignement, c'est la lettre du texte située en face de la dernière position du motif qui fixe le saut : plus ce décalage est petit, plus l'algorithme examine d'alignements.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>20 fois la lettre <code>B</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la table associe <code>B</code> à un décalage de 2. Les alignements 0, 2, …, 16 font 9 alignements, moins qu'avec la lettre <code>C</code>, dont le décalage n'est que de 1.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>20 fois la lettre <code>C</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la table associe <code>C</code> à un décalage de 1, le plus petit possible. L'algorithme examine alors toutes les positions de 0 à 16, soit 17 alignements, autant que l'algorithme naïf.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>20 fois la lettre <code>A</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la table associe <code>A</code> à un décalage de 3. On n'examine que les alignements 0, 3, …, 15, soit 6.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>20 fois la lettre <code>X</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>X</code> est absent du motif, le décalage vaut donc 4, la longueur du motif. On n'examine que les alignements 0, 4, 8, 12 et 16, soit 5.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q24 : Bug subtil</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un élève écrit la boucle externe de Boyer-Moore comme<br/>
<code>while i &lt; n - m:</code> au lieu de <code>while i &lt;= n - m:</code>.<br/>
Quel est l'effet ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bug très classique des problèmes de bornes :<br/>
<code>&lt;</code> versus <code>&lt;=</code>. Un test sur <code>texte = "abc"</code>,<br/>
<code>motif = "bc"</code> détecte immédiatement le bug : <code>n - m</code><br/>
vaut 1, donc <code>while i &lt; 1</code> ne teste que i=0 et rate<br/>
le motif en position 1.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'algorithme entre dans une boucle infinie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la boucle se termine bien, juste trop<br/>
tôt.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'algorithme est plus rapide (gain négligeable)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la performance n'est pas le problème.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'algorithme renvoie des positions incorrectes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les positions trouvées sont correctes,<br/>
on en rate juste certaines (celles à la fin).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>L'algorithme rate les motifs situés à la toute fin du texte</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la position <code>i = n - m</code> est la<br/>
dernière où le motif tient encore dans le texte.<br/>
La condition <code>i &lt; n - m</code> exclut cette position<br/>
et rate les occurrences finales.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q25 : Comparaison synthétique</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi les affirmations suivantes sur les algorithmes<br/>
de recherche textuelle vus en NSI, laquelle est<br/>
<strong>fausse</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>« Toujours plus rapide » est presque toujours faux en<br/>
algorithmique : chaque algorithme a ses cas<br/>
favorables et ses pathologies. Le choix dépend du<br/>
profil des données.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'algorithme naïf a une complexité O(n × m) dans le pire cas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : c'est sa complexité de pire cas standard.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Boyer-Moore-Horspool construit sa table à partir du motif seul</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : le prétraitement ne lit que le motif, avant tout parcours du texte. La même table sert donc pour n'importe quel texte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Boyer-Moore-Horspool compare le motif au texte de droite à gauche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : à chaque alignement, la comparaison commence par le dernier caractère du motif et remonte vers le premier.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Boyer-Moore-Horspool est toujours plus rapide que l'algorithme naïf</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Faux (donc bonne réponse) : sur certains textes (alphabet réduit, motif répétitif), les décalages restent très petits et Boyer-Moore examine autant d'alignements que le naïf, avec en plus le travail de consultation de la table.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q26 : Code de l'algorithme naïf</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle fonction Python illustre l'algorithme naïf de<br/>
recherche textuelle par comparaison <strong>caractère par<br/>
caractère</strong>, en renvoyant la liste des indices de<br/>
début de chaque occurrence ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cet algorithme illustre clairement le schéma de<br/>
double boucle (externe sur les positions, interne<br/>
sur la comparaison caractère par caractère).<br/>
C'est la base pédagogique avant d'aborder<br/>
Boyer-Moore.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def recherche_naif(texte, motif):
    for i in range(len(texte)):
        if texte[i] == motif:
            return i
    return -1</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on compare un seul caractère du texte<br/>
avec <strong>toute la chaîne</strong> motif, ce qui est<br/>
toujours faux (sauf si le motif est de<br/>
longueur 1). Et on ne renvoie qu'une seule<br/>
position au lieu de toutes les occurrences.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>def recherche_naif(texte, motif):
    positions = []
    n, m = len(texte), len(motif)
    for i in range(n - m + 1):
        j = 0
        while j &lt; m and texte[i + j] == motif[j]:
            j += 1
        if j == m:
            positions.append(i)
    return positions</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la boucle externe parcourt les<br/>
positions valides ; la boucle interne compare<br/>
caractère par caractère et s'arrête au premier<br/>
échec. Si on a comparé tous les caractères du<br/>
motif (<code>j == m</code>), on a trouvé une occurrence.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def recherche_naif(texte, motif):
    positions = []
    for i in range(len(texte)):
        if texte[i] == motif[0]:
            positions.append(i)
    return positions</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on ne compare que le premier<br/>
caractère du motif, jamais les suivants.<br/>
Pour <code>motif = "abra"</code> dans<br/>
<code>"abracadabra"</code>, ce code renvoie<br/>
<code>[0, 3, 5, 7, 10]</code>, toutes les positions<br/>
de <code>'a'</code>, alors que les occurrences de<br/>
<code>"abra"</code> commencent aux indices <code>0</code> et <code>7</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>def recherche_naif(texte, motif):
    positions = []
    for i in range(len(texte)):
        if texte[i:i + len(motif)] == motif:
            positions.append(i)
    return positions</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette version fonctionne, mais utilise une<br/>
comparaison de tranches qui repose sur<br/>
l'opération <code>==</code> de Python. Elle masque la<br/>
mécanique caractère par caractère qu'on<br/>
souhaite illustrer dans l'algorithme naïf<br/>
pédagogique. De plus, la boucle va trop loin<br/>
(jusqu'à <code>len(texte) - 1</code>), ce qui peut<br/>
provoquer des comparaisons inutiles avec des<br/>
tranches plus courtes que <code>m</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q27 : Saut maximal en pratique</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Avec le motif <code>motif = "exercice"</code> (longueur 8) et<br/>
le texte <code>"élève fait son devoir"</code>, on aligne le<br/>
motif au tout début. Le caractère du texte aligné<br/>
avec la fin du motif est <code>'a'</code> (de « fait »).<br/>
Sachant que <code>'a'</code> n'apparaît pas dans <code>"exercice"</code>,<br/>
de combien décale-t-on ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>C'est ce mécanisme de saut maximal qui rend<br/>
Boyer-Moore sous-linéaire dans le meilleur cas :<br/>
pour des textes en alphabet riche (lettres latines,<br/>
ponctuation), la plupart des caractères du texte<br/>
sont absents du motif, et on saute donc presque<br/>
toujours de <code>m</code> positions.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>1 position</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est ce que ferait l'algorithme naïf<br/>
(avancer d'une position après chaque échec).<br/>
L'intérêt de Boyer-Moore est précisément de<br/>
sauter davantage en s'appuyant sur la table<br/>
de décalages.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>0 position (on doit tester à nouveau au même endroit)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un décalage de 0 ferait boucler<br/>
l'algorithme indéfiniment. C'est précisément<br/>
pour cela qu'on exclut le dernier caractère<br/>
du motif lors du pré-traitement de la table<br/>
de décalages.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>4 positions (la moitié de la longueur du motif)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Boyer-Moore ne fait pas de demi-saut<br/>
arbitraire. La règle est claire : si le<br/>
caractère est absent du motif, on saute de<br/>
la longueur entière <code>m</code> du motif.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>8 positions (la longueur du motif)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>'a'</code> n'étant pas présent dans<br/>
<code>"exercice"</code>, on peut sauter de toute la<br/>
longueur du motif sans risque de manquer une<br/>
occurrence. C'est le saut maximal possible.<br/>
Sur du texte courant, ce type de saut est<br/>
fréquent et explique la rapidité de<br/>
Boyer-Moore.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q28 : Un texte deux fois plus long</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On cherche le même motif dans un texte deux fois plus long, avec<br/>
l'algorithme naïf. Comment évolue le temps de recherche, dans le<br/>
pire cas ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le coût du naïf est en $O(n \times m)$ : linéaire en chacune des<br/>
deux longueurs.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il double environ, le coût étant proportionnel à la longueur du texte</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le pire cas coûte de l'ordre de $n \times m$<br/>
comparaisons ; à motif fixé, le coût est linéaire en $n$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il quadruple, le coût étant proportionnel au carré de la longueur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le facteur $m$ est la longueur du motif, qui n'a pas<br/>
changé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il ne change pas, seule la longueur du motif comptant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : chaque position du texte est un alignement à tester.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il est divisé par deux, les occurrences étant plus faciles à trouver</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un texte plus long ne rend rien plus facile.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q29 : Le meilleur cas de Boyer-Moore</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un texte de $1000$ caractères, un motif de $10$ caractères. Dans<br/>
le meilleur cas, à chaque alignement, le dernier caractère comparé<br/>
est absent du motif et l'algorithme de Boyer-Moore saute de $10$<br/>
positions. Combien de comparaisons fait-il environ ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Boyer-Moore peut faire moins de comparaisons que le texte n'a de<br/>
caractères : un motif long sur un alphabet riche donne des sauts<br/>
longs.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$100$, une par saut de $10$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : une seule comparaison par alignement, et<br/>
$1000 / 10 = 100$ alignements. Le texte est lu en sautant la<br/>
plupart de ses caractères.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$1000$, une par caractère du texte</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les caractères sautés ne sont jamais comparés.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$10000$, le pire cas du naïf</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : $n \times m$ est le pire cas de l'algorithme naïf, à<br/>
l'opposé de ce meilleur cas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$10$, une par caractère du motif</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il faut bien parcourir tout le texte, par sauts.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q30 : Trouver toutes les occurrences</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>L'algorithme de recherche renvoie la position de la première<br/>
occurrence. Que faut-il changer pour obtenir toutes les<br/>
occurrences ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une recherche de toutes les occurrences renvoie une liste de<br/>
positions, éventuellement vide.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Mémoriser chaque position trouvée et continuer le parcours au lieu de renvoyer</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : au lieu d'un <code>return</code> dès la première<br/>
occurrence, on ajoute la position à une liste et on poursuit<br/>
jusqu'à la fin du texte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Relancer la recherche depuis le début du texte après chaque occurrence</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on retrouverait toujours la même première occurrence.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Rien, un algorithme de recherche ne peut trouver qu'une occurrence</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il suffit de ne pas s'arrêter à la première.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Chercher le motif à l'envers pour trouver la dernière occurrence</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on obtiendrait une occurrence, pas toutes.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q31 : Un motif plus long que le texte</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Le motif cherché est plus long que le texte. Que renvoie une<br/>
recherche naïve correctement écrite, et au prix de combien de<br/>
comparaisons ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les cas limites, motif vide ou motif plus long que le texte, se<br/>
testent avant tout : un bon algorithme les traite sans travail.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Aucune occurrence, sans aucune comparaison de caractères</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : il n'existe aucun alignement possible, la boucle<br/>
sur les positions ne fait aucun tour.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur d'exécution, l'indice dépassant la fin du texte</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une boucle bornée par <code>n - m + 1</code> ne fait aucun tour<br/>
quand cette borne est négative.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une occurrence à la position $0$, le début coïncidant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une occurrence exige que tout le motif soit présent.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune occurrence, après avoir comparé tous les caractères du texte</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune comparaison n'est nécessaire, faute<br/>
d'alignement.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q32 : Le pire cas du naïf en chiffres</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Le texte est formé de $10$ lettres <code>a</code>. Le motif est formé de<br/>
$2$ lettres <code>a</code> suivies d'un <code>b</code>. L'algorithme naïf compare de<br/>
gauche à droite et s'arrête au premier échec. Combien de<br/>
comparaisons fait-il en tout ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un texte répétitif et un motif qui n'échoue qu'à la fin font<br/>
payer au naïf son coût maximal, proche de $n \times m$.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$24$, soit $8$ alignements de $3$ comparaisons</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : à chaque alignement, les $2$ premiers<br/>
caractères coïncident et seul le <code>b</code> final échoue : $3$<br/>
comparaisons, pour chacun des $8$ alignements.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$10$, une par caractère du texte</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : chaque alignement relit les mêmes caractères.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$8$, une seule par alignement tenté</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : chaque alignement coûte $3$ comparaisons, l'échec<br/>
n'arrivant qu'au dernier caractère.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$30$, soit $10$ alignements de $3$ comparaisons</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il n'y a que $8$ alignements possibles.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q33 : Les comparaisons d'un seul alignement</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>À un alignement donné, l'algorithme naïf compare le motif <code>abxyz</code><br/>
à la portion de texte <code>abcde</code>, caractère par caractère de gauche à<br/>
droite, et s'arrête au premier échec. Combien de comparaisons<br/>
fait-il ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'arrêt au premier échec est ce qui rend le naïf rapide en<br/>
pratique : la plupart des alignements échouent dès les premiers<br/>
caractères.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$3$, jusqu'au premier échec inclus</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : les premiers caractères coïncident, et la<br/>
comparaison qui échoue est la $3$-ième ; l'alignement est<br/>
abandonné aussitôt.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$5$, tous les caractères du motif</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : après un échec, inutile de comparer la suite.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$1$, le premier caractère seulement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la comparaison continue tant que les caractères<br/>
coïncident.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$0$, les deux mots étant différents</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : savoir qu'ils diffèrent demande justement des<br/>
comparaisons.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q34 : Le décalage après un échec</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans l'algorithme naïf, de combien de positions décale-t-on le<br/>
motif après un alignement qui échoue ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le naïf avance toujours d'un cran ; Boyer-Moore gagne en avançant<br/>
davantage quand c'est sans risque.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>D'une seule, quel que soit l'endroit de l'échec</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le naïf ne tire aucune information de l'échec ;<br/>
il essaie la position suivante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>De la longueur du motif, pour ne pas revenir en arrière</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on manquerait les occurrences qui commencent à<br/>
l'intérieur de l'alignement raté.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Jusqu'au caractère qui a provoqué l'échec</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est une idée de Boyer-Moore, pas du naïf.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>De deux positions, pour aller plus vite</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sauter une position manquerait des occurrences.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q35 : Boyer-Moore avec un motif d'un seul caractère</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On cherche un motif réduit à un seul caractère avec l'algorithme<br/>
de Boyer-Moore. Comment se comporte-t-il ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>L'avantage de Boyer-Moore grandit avec la longueur du motif ; sur<br/>
un motif très court, il se réduit au naïf.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il examine chaque caractère du texte, comme le naïf</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le saut maximal vaut la longueur du motif, soit<br/>
$1$ ; chaque alignement coûte une comparaison et avance d'une<br/>
position. Aucun gain possible.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il saute de deux caractères en deux, grâce à sa table</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un saut de deux manquerait un caractère du texte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il échoue aussitôt, la table de décalage étant vide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une table vide donne le saut par défaut, $1$, et tout<br/>
fonctionne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il ne compare qu'un caractère du texte sur deux</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : chaque caractère du texte doit être examiné.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Recherche textuelle — Q36 : Chercher un mot entier</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La recherche du motif <code>art</code> dans <code>partir</code> renvoie une occurrence,<br/>
alors que l'on voulait le mot entier. Comment restreindre la<br/>
recherche aux mots entiers ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les algorithmes de recherche travaillent sur des caractères, pas<br/>
sur des mots : la notion de mot entier s'ajoute par un test sur<br/>
les voisins.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Vérifier que les caractères voisins de l'occurrence ne sont pas des lettres</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : une occurrence est un mot entier si elle est<br/>
bordée, de chaque côté, par un espace, une ponctuation ou le<br/>
bord du texte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Chercher le motif en majuscules, les mots entiers commençant par une majuscule</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la casse n'a aucun rapport avec les limites de mots.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Utiliser Boyer-Moore, qui ne trouve que des mots entiers</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : Boyer-Moore cherche des sous-chaînes, exactement comme<br/>
le naïf.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Ajouter un espace au début du motif seulement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cela manquerait les mots en début de texte et<br/>
accepterait <code>artiste</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
