corrigé

publicité
INF123 - Examen
12 mai 2016
Éléments de correction
Partie 1 : Ensembles de mots (∼ 5 points)
Question 1 :
(0,5 point) Dessinez un exemple de valeur de la variable noms (déclarée ligne 21) représentant l’ensemble
{crayon, chat, papillon, gendarme, potage, bateau}.
tab
crayon
card
6
chat
papillon
gendarme
potage
bateau
Question 2 :
(2,5 points) Écrivez les fonctions :
— init vide (lignes 23-25) qui initalise un ensemble vide.
— est vide (lignes 27-29) qui retourne 1 si e est vide, 0 sinon.
— chercher (lignes 31-33) qui recherche le mot m dans l’ensemble e et qui retourne
— l’indice où se trouve m s’il est présent dans e,
— -1 sinon.
— ajouter (lignes 35-37) qui ajoute le mot m à l’ensemble e, s’il n’est pas déjà présent.
void i n i t v i d e ( ens mots ∗e ) {
e−>c a r d=0 ;
}
i n t e s t v i d e ( ens mots ∗e ) {
r e t u r n e−>c a r d==0 ;
}
i n t ch er c he r ( ens mots ∗e , char m[ ] ) {
i n t i =0 ;
w h i l e ( i <e−>c a r d && strcmp ( e−>tab [ i ] , m) ) {
i++ ;
}
i f ( i==e−>c a r d ) r e t u r n −1 ;
e l s e return i ;
}
void a j o u t e r ( ens mots ∗e , char m[ ] ) {
int i ;
i=c h e r c h e r ( e , m) ;
i f ( i ==−1) {
s t r c p y ( e−>tab [ e−>c a r d ] , m) ;
e−>c a r d++ ;
}
}
Question 3 :
(2 points) Écrivez la fonction initialiser (lignes 39-41) qui initialise l’ensemble de mots m à partir des
mots contenus dans le fichier de nom nom fich. Si l’ouverture du fichier est impossible, un message d’erreur
approprié est affiché et le programme se termine.
void i n i t i a l i s e r ( ens mots ∗e , char nom fich [ ] ) {
FILE ∗ f ;
c h a r mot [LG MAX MOTS] ;
f=f o p e n ( n o m f i c h , ” r ” ) ;
i f ( f==NULL) {
f p r i n t f ( s t d e r r , ” o u v e r t u r e de %s i m p o s s i b l e \n ” , n o m f i c h ) ;
exit (2) ;
}
init vide (e) ;
f s c a n f ( f , ”%s ” , mot ) ;
while ( ! f e o f ( f )) {
a j o u t e r ( e , mot ) ;
f s c a n f ( f ,”% s ” , mot ) ;
}
fclose ( f ) ;
}
Partie 2 : Lignes (∼ 5 points)
Question 4 :
(2 points) Écrivez la fonction lire ligne (lignes 43-46) dont la spécification est la même que la fonction
lire ligne de l’interpréteur : f étant un descripteur de fichier ouvert en lecture, la fonction lit et stocke dans
phrase la prochaine ligne de ce fichier sous la forme d’une chaı̂ne de caractères, c’est-à-dire en remplaçant
le ’\n’ par ’\0’. Elle renvoie 0 si la fin de fichier est atteinte sans qu’aucun caractère n’ait été lu, 1 sinon.
i n t l i r e l i g n e ( FILE ∗ f , c h a r p h r a s e [ ] ) {
char c ;
i n t i =0 ;
f s c a n f ( f , ”%c ” , &c ) ;
w h i l e ( ! f e o f ( f ) && c ! = ’ \ n ’ ) {
p h r a s e [ i ]= c ;
i++ ;
f s c a n f ( f , ”%c ” , &c ) ;
}
phrase [ i ]= ’\0 ’ ;
i f ( f e o f ( f ) && ( i ==0)) r e t u r n 0 ;
e l s e return 1 ;
}
Question 5 :
(3 points) Écrivez la fonction prochain mot.
v o i d p r o c h a i n m o t ( c h a r p h r a s e [ ] , i n t ∗ i n d c o u r , c h a r mot [ ] ) {
i n t i =0 ;
i n t j =∗ i n d c o u r ;
w h i l e ( p h r a s e [ j ]== ’ ’ ) {
j++ ;
}
w h i l e ( p h r a s e [ j ] ! = ’ \ 0 ’ && p h r a s e [ j ] ! = ’ ’ ) {
mot [ i ]= p h r a s e [ j ] ;
i ++;
j ++;
}
mot [ i ] = ’ \ 0 ’ ;
∗ i n d c o u r=j ;
}
Partie 3 : Automate reconnaisseur (∼ 5 points)
Question 6 :
(1 point) Dessinez l’automate obtenu en ajoutant un nouvel état de numéro 6 vers lequel vont toutes les
transitions qui ne sont pas dessinées sur l’automate de la figure 3, en particulier les transitions étiquetées
par INCONNU.
Indication : l’état 6 est un état puits, c’est-à-dire que toutes les transitions issues de l’état 6 mènent à
l’état 6.
2
ARTICLE
NOM
0
VERBE
1
ARTICLE
2
NOM
3
4
5
<>VERBE
<>ARTICLE
<>NOM
<>NOM
6
<> ARTICLE
TOUT
TOUT
Question 7 :
(1 point) En considérant l’ensemble d’entrées {ARTICLE, ADJECTIF, NOM, VERBE, CONJONCTION, INCONNU},
complétez l’automate pour tenir compte des adjectifs et des conjonctions. Veillez à ce que de chaque état
soit issue une et une seule transition pour chaque entrée possible.
CONJONCTION
ADJECTIF
ADJECTIF
ADJECTIF
ADJECTIF
ARTICLE
0
NOM
VERBE
1
2
ARTICLE
3
4
NOM
5
<>{VERBE, ADJECTIF}
<.>{NOM, ADJECTIF}
<>ARTICLE
<.>{NOM, ADJECTIF}
6
<>{CONJONCTION, ADJECTIF}
<> ARTICLE
TOUT
Question 8 :
(1 point) Représentez la fonction de transition de votre automate par un tableau à deux dimensions dont
les lignes sont indexées par les numéros des états (de 0 à 6), et les colonnes par les entrées.
Etat\Entree
0
1
2
3
4
5
0
ARTICLE
1
6
6
4
6
6
6
ADJECTIF
6
1
2
6
4
5
6
NOM
6
2
6
6
5
6
6
VERBE
6
6
3
6
6
6
6
CONJONCTION
6
6
6
6
6
0
6
INCONNU
6
6
6
6
6
6
6
Question 9 :
(2 points) La fonction analyse renvoie 1 si la chaı̂ne phrase en argument est reconnue par l’automate, 0
sinon. À l’aide des fonctions prochain mot et nature mot, complétez cette fonction.
i n t analyse ( char phrase [ ] ) {
i n t t r a n s i t i o n [ 7 ] [ 6 ] ={
/∗ de 0 ∗ / { 1 , 6 , 6 , 6 , 6 , 6 } ,
/∗ de 1 ∗ / { 6 , 1 , 2 , 6 , 6 , 6 } ,
/∗ de 2 ∗ / { 6 , 2 , 6 , 3 , 6 , 6 } ,
/∗ de 3 ∗ / { 4 , 6 , 6 , 6 , 6 , 6 } ,
/∗ de 4 ∗ / { 6 , 4 , 5 , 6 , 6 , 6 } ,
/∗ de 5 ∗ / { 6 , 5 , 6 , 6 , 0 , 6 } , /∗ t o u t bon ∗/
/∗ de 6 ∗ / { 6 , 6 , 6 , 6 , 6 , 6} /∗ p o u b e l l e ∗/
} ;
i n t i =0 ;
c h a r mot [LG MAX MOTS] ;
i n t e t a t c o u r =0 ;
3
int etat suiv ;
int entree ;
while ( phrase [ i ]!= ’\0 ’) {
p r o c h a i n m o t ( p h r a s e , &i , mot ) ;
e n t r e e=n a t u r e m o t ( mot ) ;
e t a t s u i v=t r a n s i t i o n [ e t a t c o u r ] [ e n t r e e ] ;
e t a t c o u r=e t a t s u i v ;
}
r e t u r n ( e t a t c o u r ==5) ;
}
Partie 4 : Shell (∼ 2 points)
Question 10 :
(2 points) Écrivez un script shell qui prend en arguments un ou plusieurs noms de fichiers contenant des
phrases et qui affiche pour chacun d’eux :
— les phrases du fichier <nom du fichier> sont correctes
si toutes les phrases du fichier son correctes
— le fichier <nom du fichier> contient au moins une phrase incorrecte
sinon.
De plus, le script affichera un message d’erreur si aucun argument ne lui est fourni, ou si un des arguments
n’est pas le nom d’un fichier existant.
Indications : Si toutes les phrases du fichier analysé sont correctes, le programme analyser ne produit
pas d’affichage. Sinon, une ligne est affichée par l’instruction de la ligne 113. On rappelle (cf memo-bash)
que le test [ -n <cha^
ıne> ] vaut vrai si la chaı̂ne n’est pas vide.
#!/ b i n / bash
i f [ $# −eq 0 ]
then
echo $0 n e c e s s i t e au moins un argument
exit
fi
for
do
file
in $∗
i f [ ! −f $ f i l e ]
then
echo ” $ f i l e n ’ e x i s t e pas ”
else
i n c o r r e c t=$ ( . / a n a l y s e r A r t i c l e s Noms A d j e c t i f s Verbes C o n j o n c t i o n s $ f i l e
| g r e p ’ pas c o r r e c t e ’ )
i f [ −n ” $ i n c o r r e c t ” ]
then
echo ” $ f i l e c o n t i e n t au moins une p h r a s e i n c o r r e c t e ”
else
echo ” l e s p h r a s e s du f i c h i e r $ f i l e s o n t c o r r e c t e s ”
fi
fi
done
Partie 5 : Intersection d’ensembles (∼ 3 points)
Question 11 :
(2 points) Écrivez une fonction de profil
void intersection(ens mots *A, ens mots *B, ens mots *C) (lignes 80-82)
qui construit dans C l’intersection des ensembles A et B.
Indications
— Utilisez les fonctions sur les ensembles de mots de la partie 1.
— Les ensembles ne sont pas triés. Un algorithme possible est le suivant : pour chaque élément de A, on
cherche s’il est dans B, si oui, on l’ajoute à C.
v o i d i n t e r s e c t i o n ( e n s m o t s ∗A, e n s m o t s ∗B, e n s m o t s ∗C) {
4
int i ;
i n i t v i d e (C) ;
f o r ( i =0 ; i < A−>c a r d ; i ++) {
i f ( c h e r c h e r (B, A−>tab [ i ] ) != −1) {
a j o u t e r (C, A−>tab [ i ] ) ;
}
}
}
Question 12 :
(1 point) Complétez la fonction main en signalant par un message si les ensembles des noms et des
adjectifs, ou si les ensembles des noms et des verbes, ont une intersection non vide (on ne teste pas d’autres
intersections d’ensembles). Ne recopiez pas toute la fonction main, indiquez les modifications apportées à
l’aide des numéros de lignes.
e n s m o t s InterNomsAdjs , InterNomsVerbes ;
i n t e r s e c t i o n (&noms , &a d j e c t i f s , &InterNomsAdjs ) ;
i n t e r s e c t i o n (&noms , &v e r b e s , &InterNomsVerbes ) ;
i f ( ! e s t v i d e (& InterNomsAdjs ) ) {
p r i n t f ( ” A t t e n t i o n : homonymies e n t r e noms e t a d j e c t i f s \n ” ) ;
}
i f ( ! e s t v i d e (& InterNomsVerbes ) ) {
p r i n t f ( ” A t t e n t i o n : homonymies e n t r e noms e t v e r b e s \n ” ) ;
}
Bonus : intersection de séquences triées (∼ 2 points)
Question 13 :
(2 points) a) La fonction intersection que vous avez écrite à la question 11 répond-elle au problème
(c’est-à-dire, si A et B sont triés, est-ce que C l’est) ? Justifiez votre réponse
b) En tirant parti du fait que A et B sont triés, écrivez une nouvelle fonction C intersection triee
(lignes 84-86) plus efficace.
On rappelle que la comparaison selon l’ordre lexicographique des chaı̂nes de caractères s’effectue avec la
fonction int strcmp(char ch1[], char ch2[]) dont le résultat est négatif, nul ou positif selon que ch1
est avant ch2, égal à ch2, ou après ch2 dans l’ordre lexicographique.
a) Oui : les mots de A, triés par ordre croissants sont examinés dans cet ordre et insérés le cas échéant selon le
même ordre.
v o i d i n t e r s e c t i o n t r i e e ( e n s m o t s ∗A, e n s m o t s ∗B, e n s m o t s ∗C) {
int i , j , k ;
i n t rescomp ;
i n i t v i d e (C) ;
i =0 ; j =0 ; k=0 ;
w h i l e ( i < A−> c a r d && j < B−> c a r d ) {
rescomp= strcmp (A−>tab [ i ] , B−>tab [ j ] ) ;
i f ( rescomp==0) {
s t r c p y (C−>tab [ k ] , A−>tab [ i ] ) ;
i++ ; j++ ; k++ ;
}
e l s e i f ( rescomp <0)
i++ ;
else
j ++;
}
C−>c a r d=k ;
}
5
Téléchargement