Vous êtes sur la page 1sur 7

Université de Rouen Normandie Master Informatique

UFR Sciences et Techniques 2017-2018

Algorithmique du texte
Contrôle continu no 1
Date : 16 octobre 2017. Durée : 1 h. Documents, baladeurs, casques audio, oreillettes, calcu-
latrices, mobiles, tablettes, portables... interdits. Le barème est donné à titre indicatif.
Exercice 1 (5 points.)
1) Énoncez le lemme de périodicité de Fine et Wilf.
2) Donnez l’ensemble des mots qui admettent 3, 4 et 10 comme périodes mais pas 1. Rédigez,
justifiez et faites appel au dit lemme de manière judicieuse.
3) Même chose pour 3, 5 et 9.
4) Même chose pour 3, 6 et 8.
Exercice 2 (10 points.)
Soit A un alphabet. Soit h : A∗ → A∗ la fonction définie par :
h(ε) = ε ;
h(ua) = h(u) · a · h(u), pour tout mot u ∈ A∗ et toute lettre a ∈ A.

1) Pour a, b, c, d ∈ A, calculez h(abcd).


2) Pour tout mot u ∈ A∗ et toute lettre a ∈ A, le mot h(u) est clairement un bord de h(ua).
En est-il le bord ? Si oui, apportez-en la preuve. Si non, il vous suffit de donner un contre exemple.
3) Exprimez |h(x)| en fonction de |x| pour tout mot x ∈ A∗ . Justifiez.
4) Donnez une condition suffisante sur le mot x ∈ A∗ pour que le bord de h(x) soit de longueur
inférieure ou égale à b|h(x)|/2c. MÀJ 16-10
Coquille :
5) Le renversé d’un mot x ∈ A∗ est noté x R . Pour la suite, vous pourrez supposé établi que b|x|/2c →
(x1 · x2 · . . . · xn )R = xn R · . . . · x2 R · x1 R pour tous mots x1 , x2 , . . . , xn ∈ A∗ . b|h(x)|/2c ;
Montrez que, pour tout mot x ∈ A∗ , h(x) est un palindrome. +1 point pour
chacun.
6) Caractérisez les mots x ∈ A∗ pour lesquels la période de h(x) égale 1. Justifiez.
7) Même question, mais avec la période 2.
Exercice 3 (5 points.)
Une manière simple d’implanter de manière relativement performante l’algorithme naïf consiste
à ne recourir à la comparaison contenu de la fenêtre sur le texte contre contenu du mot cherché
que lorsque la première lettre du mot apparait à gauche dans la fenêtre. Et, pour que la recherche
des occurrences de la première lettre du mot soit performante, à recourir à une fonction spécialisée.
Il vous est demandé ici de donnez corps à la fonction de prototype
void *naive_search1(const void *pat, size_t patlen, const void *text,
size_t textlen);
qui recherche la première occurrence du bloc de caractères pointé par pat et de longueur patlen
dans le bloc de caractères pointé par text et de longueur textlen. Si une telle occurrence existe,
la fonction renvoie l’adresse du bloc trouvé. Si patlen vaut zéro, ou si la valeur de patlen est
strictement supérieure à textlen, ou encore si une telle occurrence n’existe pas, la fonction renvoie
NULL.
La fonction spécialisée à utiliser est la fonction standard memchr. La fonction de comparaison
des contenus de la fenêtre et du mot est la fonction standard memcmp.
Algorithmique du texte
2017-2018 | 2

#include <stddef.h>
NULL

#include <string.h>
void *memchr(const void *s, int c, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);

Extraits de la norme C11 :


The memcmp function compares the first n characters of the object pointed to by s1 to the
first n characters of the object pointed to by s2.
The memcmp function returns an integer greater than, equal to, or less than zero, accordingly
as the object pointed to by s1 is greater than, equal to, or less than the object pointed to by s2.
The memchr function locates the first occurrence of c (converted to an unsigned char) in
the initial n characters (each interpreted as unsigned char) of the object pointed to by s. The
implementation shall behave as if it reads the characters sequentially and stops as soon as a
matching character is found.
The memchr function returns a pointer to the located character, or a null pointer if the
character does not occur in the object.
Algorithmique du texte
3 | 2017-2018

Coulisses et solutions des exercices


Solution de l’exercice 1
1) Si p et q sont des périodes de x telles que p + q − pgcd(p, q) 6 |x|, alors pgcd(p, q) est
aussi une période de x.
2) 10 période de x. Donc |x| > 10.
3 et 4 périodes de x. pgcd(3, 4) = 1. Donc |x| > 3 + 4 − 1 = 6 implique 1 période de x.
L’ensemble cherché est donc vide.
3) 9 période de x. Donc |x| > 9.
3 et 5 périodes de x. pgcd(3, 5) = 1. Donc |x| > 3 + 5 − 1 = 7 implique 1 période de x.
L’ensemble cherché est donc vide.
4) 8 période de x. Donc |x| > 8.
3 et 8 périodes de x. pgcd(3, 8) = 1. Donc |x| > 3 + 8 − 1 = 10 implique 1 période de x.
Les seules longueurs à retenir sont donc 8 et 9.
L’ensemble cherché est constitué :
— des mots de longueur 8 de la forme abcabcab avec a, b, c ∈ A, b 6= a ou c 6= a ;
— des mots de longueur 9 de la forme abaabaaba avec a, b ∈ A et b 6= a.
Solution de l’exercice 2
1) h(abcd) = abacabadabacaba.
2) Pour u = a, h(u) = h(a) = a et h(ua) = h(aa) = aaa.
Il s’ensuit que le bord de h(ua) est aa et qu’il diffère de h(u) qui est a.
3) |h(x)| = 2|x| − 1.
Cette identité provient de ce que :
— deux mots de même longueur ont des images par h qui ont la même longueur ;
— en désignant par hn la longueur de l’image par h de tout mot de longueur n :

0, si n = 0 ;
hn =
1 + 2hn−1 , sinon.
4) La dernière lettre de x n’apparait nulle part ailleurs dans x.
Remarquons que cette condition n’est pas nécessaire : il suffit de considérer le mot x = aba
avec a, b ∈ A et a 6= b.
5) Par récurrence sur |x|.
Base : |x| = 0. Dans ce cas, x = ε et donc h(x) = ε. Comme ε est un palindrome, h(x) est
un palindrome.
Induction : |x| > 1. Soient u ∈ A∗ et a ∈ A tels que x = ua. Alors :
(h(ua))R = (h(u) · a · h(u))R
= (h(u))R · aR · (h(u))R
= h(u) · a · h(u)
= h(ua).
Ce qui montre que (h(x))R = h(x), et donc que h(x) est un palindrome.
6) Nous allons montrer que, pour toute lettre a et tout naturel n, x = an si et seulement
n
si h(x) = a2 −1 . Il vient de cette propriété que x est de période 1 si et seulement si h(x) est de
période 1. Ce qui caractérise l’ensemble des mots x pour lesquels h(x) est de période 1.
Implication. Récurrence triviale.
n
Réciproque. Par récurrence sur n. Base : n = 0. Trivial. Induction : n > 1. On a h(x) = a2 −1 =
n−1 n−1
a2 −1 · a · a2 −1 . Comme |x| > 1, il existe un mot x 0 de longueur strictement inférieure à celle de
Algorithmique du texte
2017-2018 | 4
n−1
x et une lettre b tels que x = x 0 b. D’où h(x) = h(x 0 ) · b · h(x 0 ). Par identification, h(x 0 ) = a2 −1
et b = a. Par application de l’hypothèse de récurrence, x 0 = an−1 . Il vient donc x = an−1 · a = an .
7) Nous allons montrer que, pour toutes lettres a et b, pour tout naturel k, x = abk si et
k
seulement si h(x) = (ab)2 −1 a. Il vient de cette propriété que x est de la forme abk si et seulement si
h(x) est de période 2. Ce qui caractérise l’ensemble des mots x pour lesquels h(x) est de période 1.
Implication. Par récurrence sur k. Base : k = 0. Trivial. Induction : k > 1. h(x) = h(abk ) =
k−1 k−1 k k
h(abk−1 ) · b · h(abk−1 ) = (ab)2 −1 a · b · (ab)2 −1 a = (ab)2 −2+1 a = (ab)2 −1 a.
Réciproque. Par récurrence sur k. Base : k = 0. Trivial. Induction : k > 1. On a h(x) =
k k−1 k−1
(ab) −1 a = (ab)2 −1 a·b·(ab)2 −1 a. Comme |x| > 2, il existe un mot x 0 de longueur strictement
2

inférieure à celle de x et une lettre c tels que x = x 0 c. D’où h(x) = h(x 0 )·c ·h(x 0 ). Par identification,
k−1
h(x 0 ) = (ab)2 −1 a et c = b. Par application de l’hypothèse de récurrence, x 0 = abk−1 . Il vient
donc x = abk−1 · b = abk .
Solution de l’exercice 3
void *naive_search1(const void *pat, size_t patlen, const void *text,
size_t textlen) {
if (patlen == 0 || patlen > textlen) {
return NULL;
}
int c = ((const char *) pat)[0];
const char *t = text;
while (1) {
t = memchr(t, c, (size_t) ((const char *) text + textlen - patlen + 1 - t));
if (t == NULL) {
return NULL;
}
if (memcmp(t + 1, (const char *) pat + 1, patlen - 1) == 0) {
return (void *) t;
}
++t;
}
}
Université de Rouen Normandie Master Informatique
UFR Sciences et Techniques 2017-2018

Algorithmique du texte
Contrôle continu no 2
Date : 19 décembre 2017. Durée : 1 h. Documents, baladeurs, casques audio, oreillettes,
calculatrices, mobiles, tablettes, portables... interdits. Le barème est donné à titre indicatif.
Exercice 1 (6 points.)
Pour le mot x = aabaaabaacaa :
1) Dressez, dans un même tableau, les tables bon-préf et meil-préf de x.
2) Dessinez l’automate de Simon, c’est-à-dire l’automate complet déterministe qui reconnait
l’ensemble des mots de suffixe x mais qui est privé de ses flèches nulles. Vous adjoindrez à l’étiquette
a de chacune des flèches arrière (p, a, q) son décalage défini comme la quantité |p| − |q| + 1.
3) Pour chacun des trois algorithmes Morris-Pratt (table bon-préf ), Knuth-Morris-Pratt (table
meil-préf ) et Simon, déterminez, pour chaque indice k sur le mot x, le délai en k, c’est-à-dire le
nombre maximal de comparaisons effectuées sur une lettre quelconque du texte dans lequel les
occurrences de x sont cherchées lorsque cette lettre est comparée initialement à x[k]. Présentez
les résultats sous la forme d’un tableau d’entrées les algorithmes et les indices k.
Exercice 2 (8 points.)
Pour le mot x = aacaabaabaa :
1) Donnez les tables bon-suff et dern-occ.
2) Donnez les décalages appliqués à la fenêtre glissante lorsque le contenu de cette dernière
se termine par :
a) b ;
b) c ;
c) d ;
d) ba ;
e) ca ;
f) da ;
g) caa ;
h) daa ;
i) caabaa ;
j) daabaa.
Ne vous contentez pas de donner la valeur du décalage : énoncez dans chacun des cas le calcul en
faisant explicitement apparaitre les identificateurs max, bon-suff et dern-occ.
Exercice 3 (6 points.)
On cherche coder une fonction capable de renvoyer, de tout caractère fourni, sa catégorie :
espace, chiffre, majuscule, minuscule, ponctuation, autre.
On dispose de fonctions booléennes qui permettent de tester avec des couts identiques les
appartenances aux cinq premières catégories ; elles ont pour identificateur est-espace, est-chiffre,
est-majuscule, est-minuscule et est-ponctuation. On suppose que les fonctions peuvent être com-
posées avec l’opérateur ∨ pour en former de plus puissantes sans pour autant augmenter le cout
du test : si c est un caractère et que l’on veut tester s’il est un chiffre ou une majuscule, on a tout
intérêt à employer la forme
(est-chiffre ∨ est-majuscule)(c),
Algorithmique du texte
2017-2018 | 6

de cout 1, plutôt que la forme


est-chiffre(c) ∨ est-majuscule(c),
de cout 1 si c est un chiffre et de cout 1 + 1 = 2 sinon, l’évaluation des expressions booléennes
étant supposée paresseuse.
Donnez le code le plus performant possible après avoir pris connaissance du tableau des fré-
quences des caractères suivant :
catégorie espace chiffre majuscule minuscule ponctuation autre
fréquence 19 % 20 % 9% 37 % 14 % 1%
Justifiez. (Les fréquences ne sont pas fantaisistes : elles proviennent des caractères de base des
fichiers en-tête de la glibc.)
Algorithmique du texte
7 | 2017-2018

Coulisses et solutions des exercices


Solution de l’exercice 1
WARNING ! ! NO ANSWER ! !
Solution de l’exercice 2
WARNING ! ! NO ANSWER ! !
Solution de l’exercice 3
WARNING ! ! NO ANSWER ! !

Vous aimerez peut-être aussi