Vous êtes sur la page 1sur 22

USTHB Module ALGO(L2ACAD)

Faculté d’électronique et d’informatique Année 2013/2014


Département d’ informatique Section A

Solutions types de quelques exercices d’examens

Exercice 1 : EMD1 2003/2004

1. On considère deux chaînes de caractères ch1 et ch2, écrire une fonction CONCAT
qui construit une autre chaîne ch, par concaténation de ch2 à ch1 (mettre ch2 à la suite
de ch1).

Exemple:ch1 ‘b’ ‘o’ ‘n’ ‘\0’ et ch2 ‘j’ ‘o’ ‘u’ ‘r’ ‘\0’ ch ‘b’ ‘o’ ‘n’ ‘j’ ‘o’ ‘u’ ‘r’
‘\0’

2. On donne trois chaînes de caractères ch1, ch2 et ch, écrire une fonction VERIF qui
vérifie si ch est la concaténation de ch1 et ch2 (i.e concaténer ch2 à ch1 ou ch1 à ch2),
ou non.
3. Soit une matrice de caractères A(nxm) (n<=50, m<=20) ; chaque ligne de la matrice
contient une chaîne de caractères, ces chaînes sont ordonnées par ordre décroissant de
leurs longueurs (la chaîne la plus longue se trouve à ligne 0).
4. Et soit S une chaîne de longueur 19 contenant que des caractères blancs. Ecrire un
programme qui :
a- remplace chaque chaîne d’une ligne i de la matrice A par la chaîne S, si la
chaîne ch[i] peut être obtenue par concaténation de deux autres chaînes de la
matrice A.
b- effectue le compactage des lignes de la matrice A (i.e décaler toutes les
chaînes à « blanc » vers la fin de la matrice, en gardant l’ordre des autres
chaînes).

Exercice 2 (EMD1 2004/2005)


1. Soit T un vecteur d’entiers de taille N<=50. Ecrire une fonction PRODUIT qui
calcule le produit des éléments de ce vecteur.
2. On considère une matrice M d’entiers de taille (100,50). En utilisant la fonction
PRODUIT, écrire un programme qui calcule et affiche le produit de chaque ligne de
la matrice M.

Exercice 3 (EMD1 2005/2006)


Soient deux chaînes de caractères S1 et S2 de tailles <=80.
1. On considère une position I dans S1. Ecrire une fonction SOUS-CHAINE qui
vérifie si S2 est une sous-chaîne de S1 à partir de la position I de S1.
2. Ecrire le programme qui compte le nombre de fois où S2 apparaît comme sous-chaîne
dans S1.

Exemple
S1 = "informatique=traitement automatique de l’information"
S2 = "mat"
S2 apparait trois fois comme sous-chaine de S1.(à partir de : I= 5, I= 28 et I = 46)

1 S. BOUKHEDOUMA
Exercice 4 ( EMD1 2006/2007)
1. On considère une chaîne de caractères ch de longueur <=80 représentant une phrase.
Une phrase est un ensemble de mots séparés par des espaces (blancs). Ecrire une
fonction TAUTOGRAM qui vérifie si la phrase dans ch est tautogramme (i.e tous
les mots commencent par la même lettre).
2. Soit A(n,m) (n<=50, m<=80) une matrice de caractères où chaque ligne représente une
phrase. Ecrire un programme qui compte le nombre de phrases tautogrammes dans la
matrice.

Exercice 5 (EMD1 2006/2007)


1. Soit une matrice carrée d’entiers M(l, l) avec l<=10. Ecrire une fonction DIAG qui
détermine si la matrice M vérifie la propriété suivante : la somme des éléments de la
diagonale principale est égale à la somme des éléments de la deuxième diagonale.

On considère une matrice carrée A(n, n) avec n<=100.


2. Soit une position (i,j) de la matrice A. Ecrire une fonction SOUSMAT qui extrait une
sous-matrice S(l,l) avec l<=10 à partir de la position (i,j) de A (on prendra l éléments
vers la droite à partir de la colonne j et l éléments vers le bas à partir de la ligne i).
3. En utilisant les fonctions pécédentes, écrire un programme qui cherche toutes sous-
matrices S de A vérifiant la propriété DIAG et stocke leurs coordonnées (i, j) de
début, dans une structure à définir.

Exercice 6 (EMD1 LMD 2006/2007)


On considère un texte t qui est une longue chaîne de caractères de longueur <=1000, formé
d’un ensemble de mots séparés par un ou plusieurs espaces ( ) .

1. Ecrire une fonction RECUPMOT qui récupère un mot à partir d’une position i du
texte dans une chaîne de caractères ch. On considère que la longueur d’un mot ne
dépasse pas 20, i représente l’indice de début du mot dans le texte t.

2. On veut construire une liste chaînée de point d’entrée T1 contenant des éléments
structurés : chaque élément contient un mot du texte t avec son nombre d’apparitions
dans le texte (voir figure).

a. Donner la déclaration de la liste


b. Ecrire une fonction EXIST qui vérifie si un mot m donné existe déjà dans la liste
de point d’entrée T1.
c. En utilisant les fonctions RECUPMOT et EXIST, Ecrire une fonction
CONSTLIST qui construit la liste T1 à partir du texte t.

3. Ecrire une fonction SUPPRIM qui supprime tous les éléments d’une liste de point
d’entrée T1.

4. Ecrire un programme qui construit la liste T1 et crée une nouvelle liste T2 (à partir de
T1) contenant tous les éléments de T1 triés dans l’ordre croissant selon le nombre
d’apparition des mots. A la fin du programme, la liste T1 doit ête libérée.

2 S. BOUKHEDOUMA
T1
Processeur Processus scheduler

5 10 6

NULL

Exercice 7 : EMD2 06/07


On s’intéresse à la manipulation d’une liste chaînée contenant la description de voitures,
chaque élément de la liste est composé de deux champs de type chaîne de caractères chacun:
marque (constructeur : Peugeot, Volkswagen,…) et série (modèle : 407, Polo,…).
Tete
Peugeot 407 Volkswagen Polo Peugeot 206 Renault Clio

 Donner la déclaration de la liste


1. Etant donnée une marque M de voiture, écrire une fonction RECHERCHE qui
cherche la première occurrence d’une voiture de marque M dans une liste de point
d’entrèe T et renvoie la série S de la voiture. La fonction retourne 1 si une voiture de
marque M est trouvée et 0 sinon.
2. Etant donnée une marque M de voiture, écrire une fonction SUPPRIM qui supprime
la première occurrence d’une voiture de cette marque, dans une liste de point d’entrée
T.

On désire éclater la liste initiale en plusieurs listes afin d’obtenir la structure ci-dessous. Dans
une même liste, on retrouve uniquement les voitures de même marque.

Clio Megane NULL


Renault
Volkswagen Polo Golf Touareg NULL

Peugeot 407 206 307 NULL

Pile S
 Donner la déclaration de la structure
3. On considère une liste chaînée contenant uniquement les séries de voitures. Etant
donné un élément S représentant la série d’une voiture, écrire une fonction AJOUT
qui ajoute cet élément à une liste de point d’entrée T . (la liste peut être initialement
vide)
4. En utilisant les fonctions précédentes, et uniquement les primitives Initpile et
Empiler, écrire une fonction CREER qui crée la structure ci-dessus à partir de la
liste initiale de point d’entrée Tete. Cette dernière sera libérée au cours du traitement.
5. Ecrire le programme qui crée la structure à partir de la liste initiale (supposée
existante) , et affiche tous les modèles de voitures d’une marque M donnée.

Exercice 8 : EMD1 07/08

Dans cet exercice, on voudrait manipuler des événements historiques.

3 S. BOUKHEDOUMA
Partie I
Dans un premier temps, on considère que l’événement est décrit par le mois (chaîne de
caractères) de son occurrence (càd le mois où l’événement a eu lieu) et une description de
l’événement (chaîne de caractères de longueur <=50).
Exemple : "juillet ", "indépendance de l’Algérie ".
Les événements seront sauvegardés dans une liste chaînée unidirectionnelle.

Définir le type Evt décrivant un événement et le type liste.


1. Ecrire une fonction CREER qui crée le premier élément de type Evt d’une liste
chaînée de point d’entrée tete, initialement vide.
2. Ecrire une fonction INSERE qui insère un élément de type Evt dans une liste de point
d’entrée tete triée selon l’ordre croissant des mois.
3. Ecrire une fonction TAILLE qui calcule la taille ( nombre d’éléments) d’une liste de
point d’entrée tete.
4. Ecrire une fonction SUPPR qui supprime tous les éléments d’une liste de point
d’entrée tete.

Partie II
Dans cette partie, on introduit l’information année qui représente l’année d’occurrence de
l’événement.
On considère un vecteur V de taille n<=100, contenant la description d’un ensemble
d’événements historiques. Chaque événement est décrit par les informations : mois, année et
une description de l’événement.

Exemple de vecteur V

Janvier 1994 evenement1 Mars 1962 Evenement10 Janvier 2000 Evenement4 Avril 1994 Evenement2

On voudrait à partir des éléments du vecteur V, construire une structure dynamique


regroupant les événements par année d’occurrence, comme montré sur la figure ci-dessous.

1. Donner la déclaration de la structure


2. En utilisant les fonctions de la partie I, écrire une fonction CONSTSTR qui construit la
structure de la figure ci-dessous, à partir des éléments du vecteur V supposé déjà
construit. Dans une même liste, les événements sont triés par ordre croissant des mois.

1994 Janvier evenement1 Avril evenement2 Juillet evenement3 NULL

2000 janvier evenement4 …

Mars evenement10 Juillet evenement11 …


1962
vecteur T

3. Ecrire une fonction MINEVT qui retourne le nombre minimal d’événements ayant
eu lieu à une même année, à partir de la structure ci-dessus.
4. Ecrire une fonction SUPPRIME qui supprime toutes les listes correspondant aux
années ayant ce nombre minimum d’événements.
5. En utilisant les fonctions précédentes, écrire un programme qui construit la
structure, supprime toutes les années ayant un nombre minimum d’événemnts et
effectue ensuite le compactage du vecteur T (il s’agit d’éliminer les années
correspondant à des listes vides)

4 S. BOUKHEDOUMA
Exercice 9 : EMD2 - 2006/2007
On considère une liste chaînée contenant la description de processus (programmes) dans un
système multi-utilisateurs. Chaque processus est décrit par une structure st1 comportant un id
(entier), un username (chaîne de caractères ) et une priorité (entier).

T
P0 user1 1 P1 user2 3 P2 user3 2 P3 user1 3

 Donner la déclaration de la liste (on déclare d’abord la structure st1).


1. Etant donnée une priorité pr de processus, écrire une fonction SUPPRIM qui
supprime la première occurrence d’un processus de priorité pr, d’une liste de point
d’entrée T. La fonction doit renvoyer en sortie la structure st1 du processus supprimé
s’il existe, elle doit retourner 1 si la suppression est faite et 0 sinon.
On désire manipuler une structure de file (c’est une liste chaînée de type FIFO avec deux
pointeurs particuliers tête et queue) contenant des processus décrits chacun, par une
structure st2 composée de deux champs uniquement : id et username.
a. Donner la déclaration de la file (on déclare d’abord la structure st2).
2. Ecrire la primitive ENFILER qui permet de rajouter un élément de type st2 en queue
de file (celle-ci peut être initialement vide).
3. En utilisant les fonctions SUPPRIM et ENFILER, écrire une fonction CONSTFILE
qui construit à partir de la liste initiale, une file contenant tous les processus d’une
priorité pr donnée (Il s’agit de supprimer les éléments de la liste et les rajouter à la file).
Tete queue
P1 user2 P3 user1 P6 user3 NULL

La figure montre tous les processus de priorité 3 extraits de la liste initiale.


On voudrait construire la structure ci-dessous, chaque élément de la pile contient une valeur
de priorité et un lien vers la file contenant tous les processus de cette priorité.

 Donner la déclaration de la structure

P0 user1 P4 user2 NULL


1
2 P2 user3 NULL

3 P1 user2 P3 user1 P6 user3 NULL

Pile S

5 S. BOUKHEDOUMA
Exercice 10 - examen 09/10
I- Soit une mémoire organisée sous forme de blocs tous de même taille fixe tbloc (par
exemple un bloc a une taille tbloc =1024 octets). Un bloc de la mémoire peut être libre ou
occupé, il est occupé si un programme l’utilise pour son exécution et libre sinon. Chaque bloc
est identifié par un numéro entier. Les blocs libres sont organisés dans une liste chaînée de
point d’entrée L ordonnée par ordre croissant des numéros de blocs.
Exemple : les blocs de numéros 4, 6, 7, … et 40 sont libres.
L
4 6 7 40

1. Ecrire une fonction SUPPRIME qui supprime le premier élément de la liste L.


2. Ecrire une fonction INSERE qui ajoute un élément (numéro de bloc) à la liste L en
respectant l’ordre croissant.
3. On considère un programme qui doit occuper une taille t en mémoire et une liste L de
blocs libres. En utilisant les fonctions précédentes, écrire une fonction CREATLIST
qui crée une liste de point d’entrée tete contenant les numéros de blocs qui seront
occupés par ce programme. Les numéros de blocs sont pris de la liste L des blocs
libres.

II- On considère maintenant, un ensemble de programmes devant s’exécuter sur la même


machine. Un programme est identifié par un nom exécutable qui est une chaîne de caractères
(" Prog1.exe " ou "toto.com" par exemple) et une taille t en nombre d’octets correspondant à
la taille qu’il doit occuper en mémoire. Pour chaque programme, on a la liste des blocs
occupés ordonnée selon les numéros de blocs. La liste des programmes ainsi que les blocs
occupés sont organisés dans une structure de point d’entrée T comme le montre la figure
suivante :
T 1 2 3
Prog1.exe 3034

toto.com 2020 5 8

Donner la déclaration de la structure


1. Etant donné un programme de nom NP et de taille t et la liste L des blocs libres.
Ecrire une fonction AJOUT qui ajoute l’élément NP à la fin de la liste T. On doit
utiliser la fonction CREATLIST pour créer la liste des blocs nécessaires à NP.

2. Etant donnés un programme de nom NP et la liste L des blocs libres. Ecrire une
fonction DELETE qui supprime le programme NP de la liste T et libère les blocs
qu’il occupait (on utilisera les fonctions appropriées de la partie I).

3. On dispose de la description (nom et taille) d’un ensemble de n programmes dans un


vecteur v (n<=20) ; et on dispose d’une liste L de blocs libres. En utilisant les

6 S. BOUKHEDOUMA
fonctions de la partie II, écrire le programme qui construit la structure de la figure
précédente à partir du vecteur v et supprime ensuite tous les programmes ayant une
taille inférieure à une taille tmin donnée.

Exercice 11- Examen 09/10

1. Soit une pile P1 d’entiers. Ecrire une fonction CONSTPILE qui construit une pile P2
contenant pour chaque valeur de P1 sa fréquence d’apparition. On donnera la
déclaration des piles P1 et P2.

Exemple
14 5
5 1. 2. 5
23 5
5 23 1 14
14 5 3 14
5 14 2 23
P1 P2 S
2. A partir de la pile P2, écrire un programme qui construit une pile S de valeurs de P1
triée dans l’ordre croissant (le minimum au sommet). On suppose que P1 est déjà
construite.

Exercice 12 (Exam 10/11)


Dans cet exercice, on s’intéresse à la description de fichiers stockés sur une mémoire
secondaire. Un fichier est décrit une structure st composée de trois champs : un nom (chaîne
de caractères), une taille (entier long) et une date de dernière modification.
 Donner la déclaration du type st.

On dispose d’une liste chaînée de point d’entrée T contenant la description de fichiers.


Exemple
T
Nomfich1 Taille1 date1 Nomfich2 Taille2 date2 NomfichN TailleN dateN NULL

 Donner la déclaration de la liste T.

1. Etant donné un nom de fichier Nomfich, écrire une fonction EXISTE qui vérifie si le
nom de fichier existe déjà dans la liste.
2. On donne la description d’un nouveau fichier (nomfich, taille, date). Ecrire une
fonction AJOUT qui ajoute la description de ce fichier à la fin de la liste T s’il
n’existe pas déjà. La liste T peut être vide.
3. Etant données deux adresses p1 et p2 de la liste T. Ecrire une fonction PERMUTE
qui permute les contenus des deux éléments de la liste pointés par p1 et p2.
4. On désire ranger les descriptions de fichiers par ordre croissant des noms de fichiers
dans la même liste T. Ecrire une fonction TRIER qui trie la liste par ordre croissant
des noms de fichiers ; on utilisera la fonction PERMUTE.
5. Ecrire une fonction Espace_Occ qui calcule l’espace total occupé par tous les fichiers
décrits dans la liste.

7 S. BOUKHEDOUMA
6. On suppose que la liste T est déjà créée. Ecrire un programme qui :
 Ajoute à la fin de la liste, la description d’un fichier donné,
 Trie la liste par ordre croissant des noms de fichiers,
Affiche le contenu de la liste, l’espace total occupé et l’espace libre si la taille du support de stockage
est égale à E donnée.

8 S. BOUKHEDOUMA
Solutions types des exos

Exercice 1

#include<string.h>
#include<stdio.h>
1/
void CONCAT (char *ch1 , char *ch2, char *ch) )
{ int i , j , k ;
for( i=0 , k=0 ; ch1[i]!=’\0’ ; i++ , k++ )
ch[k]=ch1[i] ;
for( j=0 ; ch2[j]!=’\0’ ; j++ )
{ ch[k]=ch2[j] ; k++ ; }

ch[k]=’\0’ ; }

2/
int VERIF (char *ch1 , char *ch2 , char *ch)
{ char S[40];
CONCAT (ch1 , ch2, S ); /* S est la concaténation de ch2 à ch1*/
if ( strcmp(S , ch )= =0) return(1);
else
{ CONCAT(ch2 , ch1, S); /* S est la concaténation de ch1 à ch2 */
if(strcmp(S , ch)= =0) return(1);
}
return(0); }

void main()
{ char A[50][20] ;
int i , j , n; char S[20] ;
scanf (“%d “ , &n);
for( i=0 ; i<n ; i++) gets(A[i] ); /* remplissage de la matrice */
for( i=0 ; i<n ; i++) S[i] = ‘ ’; S[19] = ‘\0’; /* lecture de S */

for( i=0 ; i< n-2 ; i++) /* trois boucles imbriquées */


for( j= i+1 ; j<n-1 ; j++)
for( k=j+1 ; k<n ; k++)
if ( VERIF ( A[j] , A[k] , A[i] ) = = 1)
strcpy(A[i] , S); /* copier la chaîne S, à la ligne i de la matrice */

/* compactage des lignes */


bs=n ;
for( i=0 ; i< bs ; i++)
{ if (!strcmp(A[i] , S)) /*A[i] est une chaine à blanc */
{for ( j=i ; j< bs-1 ; j++) /* boucle de décalage */
strcpy( A[j] , A[j+1] );
strcpy( A[bs] , S); bs--; /* à la sortie de la boucle */
}
}
/* affichage de la matrice A */
for( i=0 ; i<n ; i++) puts(A[i] );
}

9 S. BOUKHEDOUMA
Exercice 2
1) # include<stdio.h> 2) void main()
int Produit (int *t, int n) { int M[100,50] ; int i, j ;
{ int p=1 ; int i ; for (i= 0; i<100; i++)
for (i= 0; i<n; i++) for (j= 0; j<50; j++)
p = p* t[i]; scanf (“%d”, &M[i][j]);
return(p);
} for (i= 0; i<100; i++)
printf (“le produit de la ligne %d est :%d”, i,
Produit(M[i], 50)) ;
}

Exercice 3
# include<stdio.h>
int SOUS_CHAINE (char *S1, char *S2, int I)
{int j, k ;
for (j=0, k=I ; S2[j] != ‘\0’&& S1[k] !=’\0’ ; j++, k++)
if (S2[j] != S1[k]) return (0) ;
if (S2[j] = = ‘\0’) return (1) ;
return (0) ;
}

void main()
{ char S1[80], S2[80] ; int I, lg, nb = 0 ;
puts ( donnez les deux chaînes ) ; gets (S1) ; gets (S2) ;
lg = strlen(S1) – strlen(S2) ;
for ( I=0 ; i<lg ; i++)
if (SOUS_CHAINE(S1, S2, I)) nb++ ;
printf (nb = %d , nb) ;
}

Exercice 4
# include<stdio.h>
int TAUTOGRAM (char *ch)
{int i =0 ; char c ;
while (ch[i] ==   ) i+ + ; /*sauter les 1er blancs */
c= ch[i] ; /* premier caractère du premier mot */
while (ch[i] != \0 )
{ while (ch[i] != \0  && ch[i] !=  ) i+ + ; /*sauter le mot */
while (ch[i] ==   ) i+ + ; /* sauter blancs */
if (ch[i] !=’\0’) /* début de mot */
{ if (ch[i] != c) return (0) ;

}
return (1) ;
}

void main()
10 S. BOUKHEDOUMA
{ char A[50][80]; int n, nb = 0 ;
puts ( donnez le nombre de chaînes ) ; scanf (%d, &n) ;
for ( i= 0; i<n ; i++)
{ puts ( donnez la phrase numéro %d , i) ;
gets (A[i]) ;
if (TAUTOGRAM(A[i])) nb++ ;
}
printf (nb = %d , nb) ;
}

Exercice 5
# include<stdio.h>
1/ int DIAG (int **M, int l)
{int i, S1=0 ; int S2 = 0 ;
for (i=0 ; i<l ; i++)
{ S1 = S1 +M[i][i] ; S2 = S2 + M[i][l-i-1] ; }
/* à la sortie de la boucle */
if (S1 = = S2) return (1) ;
return (0) ;
}

2/ void SOUSMAT (int ** A, int i, int j, int **S, int l)


{ int i1, j1 ;
for (i1= i ; i1< i+l ; i1++)
for (j1= j ; j1< j+l ; j1++)
S[i1-i][j1-j] = A[i1][j1] ;
}

3/ void main()
{ typedef struct {int ligne ; int colonne ;} st ;
st t[10] ; /* on déclare un vecteur de type st */
int A[100][100], S[10][10]; int n, i, j, k,l ;
puts ( donnez le nombre de lignes ) ; scanf (%d, &n) ;
for (i= 0 ; i <n ; i++) for (j = 0 ; j< n; j++) /* lecture de la matrice A */
scanf(%d, & A[i][j]) ;

puts ( donnez la dimension de la sous-matrice ) ; scanf (%d, &l)

/* extraction de sous-matrices */ k = 0 ;
for (i= 0 ; i <n-l ; i++)
for (j = 0 ; j< n-l; j++)
{ SOUSMAT(A, i, j, S, l) ;
if (DIAG(S, l) )
{ t[k].ligne = i ; t[k].colonne = j ; k ++ ;} /* sauvegarder les coordonnées de
} la sous-matrice dans t*/
/* Affichage du vecteur t de coordonnées */
for ( i= 0; i<k ; i++)
printf (%d, %d , t[k].ligne, t[k].colonne) ;
}

Exercice 6
11 S. BOUKHEDOUMA
#include<stdio.h>
#include<string.h>
#include <alloc.h>
1/ void RECUPMOT(char *t, int i, char *ch)
{ int j=0 ;
for ( ;t[i] != ' '&& t[i] != '\0' ; i++,j++)
ch[j]=t[i] ;
/* à la sortie de la boucle */ ch[j]= '\0' ;
}

2/
a / Déclaration
typedef struct { char mot[20] ; int nbocc; }st ;
typedef struct elt { st info ; struct elt *svt ;} liste;

b/ int EXISTE (liste *tete, char *m)


{ liste *p;
for(p = tete ; p!=NULL ; p=p->svt)
if( !strcmp(p->info.mot,m)) /* si la fonction strcmp retourne 0, les 2 mots sont égaux */
return(1) ;
/* à la sortie de la boucle, on arrive à p = NULL */
return(0) ;
}

c/ liste *CONSTLIST(char *t) /* à partir du texte t, on construit la liste */


{ int i=0 ;
liste *tete=NULL, p,q ;
char ch[20] ;
while(t[i] !=’\0’) /* on parcourt le texte t jusqu’à la fin */
{while(t[i]= =' ') i++ ; /* boucle pour sauter les espaces */
/* à la sortie de la boucle */
if (t[i] !=’\0’)
/*récupérer mot à partir de la position i dans une chaine ch*/
{ RECUPMOT(t,i,ch) ;
/* vérifier si le mot récupéré dans ch existe déjà dans la liste */
if ( !EXISTE(tete,ch)) /* si ch n’existe pas*/

{ p = (liste *)malloc(sizeof(liste)) ; /*créer elt*/


strcpy(p->info.mot,ch) ;
p->info.nbocc =1;
/* mise à jour des chaînages */
if (tete= =NULL) {tete=p ; q=p ;} /* c’est le premier élément créé */
else {q->svt = p ;q=p ;}
p->svt=NULL ;
}
else /* le mot récupéré existe déjà dans la liste, il suffit d’incrémenter son
nombre d’occurrences */
{ for (p = tete ; strcmp(p->info.mot,ch) ; p= p->svt) ; /* boucle vide, pour
trouver le mot dans la liste */
/* à la sortie de la boucle */
p->info.nbocc++ ;
}
}
}
12 S. BOUKHEDOUMA
return (tete) ;
}

3/ void SUPPRIME (liste **tete)


{ liste *p ;
p = *tete
while (p !=NULL)
{*tete = *tete->svt ;
free(p) ; p = *tete ;
}

4/ void main()
{liste *t1 ; liste *t2=NULL, *p1, *q1, *q2, *r ; char t[1000] ;
puts("saisir le texte t : ") ; gets (t) ;
t1 = CONSTLIST(t) ; /* construction de la liste t1 */

p2=(liste *)malloc(sizeof(liste)) ; /*créer le premier élément de la liste t2, c’est le premier de t1*/
strcpy (p2->info.mot, p1->info.mot) ;
p2->info.nbocc = p1->info.nbocc ;
p2 ->svt = NULL ;

for (p1= t1->svt ; p1 !=NULL ; p1=p1->svt) /* créer les autres éléments de la liste t2 à partir
de t1 */
{ p2 = (liste *)malloc(sizeof(liste)) ;
strcpy (p2->info.mot, p1->info.mot) ; p2->info.nbocc = p1->info.nbocc ;
/* parcourir la liste t2 afin de repérer la position où il faut insérer l’élément */
for (q2 = t2 ; q2 !=NULL && q2->info.nbocc<p2->info.nbocc; r =q2 ,q2=q2->svt) ;

/* à la sortie de la boucle vide */


if(q2 = = t2) { p2->svt=t2 ; t2=p2 ;} /* insérer en tête de liste t2 */
else {r->svt=p2 ; p2->svt=q2 ;} /* insérer au milieu ou à la fin */
}
/* à la sortie de la boucle for, on aura construit la liste t2 triée */
SUPPRIME(&t1) ; /* supprime tous les elts de t1 */
}

Exercice 7

typedef struct elt { char marque[20] ; char serie[20] ; struct elt * svt ; }liste ;
1. int RECHERCHE (liste *T, char * M, char *S)
{ liste *p ;
for (p = T; p!= NULL ; p= p->svt)
if (!strcmp(p->marque, M) /*on a trouvé la marque M */
{ strcpy(S, p->serie); return(1) ;}
return(0); /* la sortie de la boucle*/
}

2. void SUPPRIM (liste **T, char *M)


{ liste *p, *q ;
/*boucle vide pour chercher la marque M */
for (p = *T; p!= NULL && strcmp(p->marque, M) ; q=p, p= p->svt) ;
if (p = = *T) /* suppression en tête */
13 S. BOUKHEDOUMA
{ *T = *T->svt ; free(p) ;}
else
if (p != NULL) { q->svt = p->svt; free(p);}
}

typedef struct elt1 {char series[20] ; struct elt1 * svt1 ; }liste1;


typedef struct { char marq[20] ; liste1 *lien; }st ;
typedef struct eltpile { st infopile ; struct eltpile * suivant ; }pile ;

3. void AJOUT (liste **T , char *S)


{ liste1 *p , *q ;
p = (liste1 *) malloc (sizeof (liste1)) ;
strcpy ( p-> series, S) ; p->svt = NULL ;
if (*T= = NULL) *T = p ; /*liste initialement vide*/
else /* parcourir la liste jusqu’ au dernier élément */
for (q = *T; q->svt != NULL ; q = q->svt) ;
q->svt = p ;
}

4. pile * CREER (liste **tete)


{ pile *P ; char M[20] ; liste1 *T ; st x ; Initpile(&P);
while (*tete != NULL)
{ strcpy ( M, tete->marque) ;
/* créer le 1er élément de liste1 et le supprimer dans la liste initiale */
AJOUT (&T, tete->serie) ; SUPPRIM (tete, M);
while (RECHERCHE(tete, M, S)) /* tant qu’on a des voitures de marque
M */
{ AJOUT (&T, S) ; SUPPRIM (tete, M); }
/* à la sortie de la boucle */

strcpy ( x.marq, M) ; x.lien = T ; Empiler (&P, x) ;


}
}

c/ void main ( )
{ pile *R ,*P ; st x ; liste *tete; liste1 *p; char M[20];
initpile (&R) ;
P = CREER(&tete);
puts ("donnez la marque de voiture à supprimer ") ; gets (M) ;
while (!pilevide(P) && strcmp(sommetpile(S).marq, M))
{ depiler (&P, &x) ; empiler (&R, x) ; }
if (pilevide (P)
puts( “la marque n’existe pas”) ;
else
for (p = x.lien; p!= NULL ; p= p->svt1) puts (p->series); /*affichage */
while ( !pilevide(R))
{depiler (&R, &x); empiler(&P,x); }
}

14 S. BOUKHEDOUMA
Exercice 8

Partie I
typedef struct { char mois[10] ; char desc[50] ; }Evt;
typedef struct elt { Evt info; struct elt * svt ; }liste ;
1. liste * CREER (Evt x)
{ liste *tete;
tete = (liste *) malloc (sizeof (liste)) ;
tete ->info = x; tete ->svt = NULL ;
return(tete);
}

2. On écrit une fonction Numéro qui retourne le numéro du mois.

int Numero(char *mois)


{ char *month[12] = {"janvier", " fevrier ", …"décembre"} ; /* l’indice (i-1)
correspond au mois numéro i */
int i;
for (i =0 ; i<12; i ++ ); // boucle vide
if (!strcmp(mois, month[i])) return (i+1);
}
void Insere (liste **tete, Evt x)
{ liste *p, *q, *r ;

p = (liste *) malloc (sizeof (liste)) ;


p -> info = x;
/*parcourir la liste pour chercher la position d’insertion */
for (q= *tete; q != NULL && Numero(q->info.mois) <= Numero(q->info.mois) ;
r= q, q= q->svt); // boucle vide
if (q = = *tete) { p->svt = *tete ; *tete = p ;}
else {r->svt = p ; p->svt =q ;}
}

3. int taille( liste *tete)


{ liste *q; int i ;
for (i = 0, q= tete; q != NULL; i ++, q= q->svt); // boucle vide
return(i) ;
}

4 . void SUPPR ( liste **tete)


{ liste *q;
for (q= *tete; q != NULL; q=*tete);
{*tete = *tete ->svt ; free(q) ;
}

Partie II
1. typedef struct { char mois[10] ; int annee ; char desc[50] ; }Evet; // pour le vecteur V
typedef struct elt { int annee; liste *lien ; }st; // pour le vecteur T

2. void CONSTSTR (Evet *V, int n, st *T, int *n1)


{int i, j ; liste *tete, *p ; int *n1 =0 ; Evt x;
for (i=0 ; i<n ; i++)
15 S. BOUKHEDOUMA
strcpy(x.mois, V[i].mois); strcpy(x.desc, V[i].desc); /*préparer l’elt x */
/*parcourir le vecteur T pour chercher si l’année V[i].annee existe déjà */
for (j=0 ; i<=*n1 ; j++)

if (T[j].annee = = V[i].annee) /* ajouter l’élément à la liste*/


{ Insere(&T[j].lien, x) ; break ; }// sortir de la boucle j

if (j > *n1) //l’année n’existe pas encore dans le vecteur T


{T[j].lien = CREER(x) ; *n1++ ;}
}

3. int MINEVT (st *T, int n1)


{ int, nb, nbmin = Taille(T[0].lien) ;
for (i =0 ; i<n1 ; i++)
{ nb = Taille (T[i].lien
if (nb < nbmin) SUPPR(&T[I].lien) ;}
return(nbmin) ;
}

4. void SUPPRIME (st *T, int n1)


{ int nbmin = MINEVT(T, n1) /* calculer le nbre min d’évenements
for (i =0 ; i<n1 ; i++)
if (Taille (T[I].lien) = = nbmin) SUPPR(&T[I].lien) ;
}

5. void main()
{ Evet V[100], st T[100], int n, n1, i, j
scanf(“%d”, &n);
for (i =0 ; i<n ; i++)
{ gets (V[i].mois); scanf(“%d”, & V[i].mois); gets (V[i].desc);}
CONSTSTR (V, n, T, &n1);
SUPPRIME(T, n1) ;
/* compactage */ int BS = n1;
for (i =0 ; i<BS ; i++)
if (T[i].lien = = NULL)
{for (j = i+1; j<BS; j ++)
if (T[j].lien != NULL) { T[i].annee = T[j].annee ; T[i].lien = T[j].lien ;
T[BS].lien =NULL; BS--;}
if (j = = BS ) break; /* sortir de la bcle i */
}
}

Exercice 9
typedef struct { int id ; char username[20] ; int priorite; }st1 ;
typedef struct elt1 { st1 info1 ; struct elt1 * svt1 ; }liste ;

1. void SUPPRIM (liste **T, int pr, st1 *x)


{ liste *p, *q ;
/*boucle vide pour chercher l’élément de priorité pr*/
for (p = *T; p!= NULL && (p->info1).priorite != pr ; q=p, p= p->svt) ;
if (p = = NULL) return(0) ;
else
16 S. BOUKHEDOUMA
{*x.id = (p->info1).id ; strcpy(*x.username, (p->info1).username ;
*x.priorite = (p->info1).priorite ;
if (p = = *T) / *suppression en tête */
*T = *T->svt ; else q->svt = p->svt;
free(p); return(1);
}

typedef struct { int idP ; char user[20] ; }st2 ;


typedef struct elt2 {st2 info2 ; struct elt2 * svt2 ; }file ;

2. void ENFILER (file **tete , file **queue, st2 x)


{ file *p , *q ;
p = (file *) malloc (sizeof (file)) ;
p.idP = x.idP; strcpy ( p-> user, x.user) ; p->svt2 = NULL ;
if (*tete= = NULL) *tete= *queue = p ; /*file initialement vide*/
else {*queue->svt2 = p ; *queue = p ;}
}

3. void CONSTFILE (liste ** T, file **tete, file ** queue, int pr)


{ st1 x ; st2 y;
*tete = *queue = NULL;
while (SUPPRIM (T, pr, &x) ) /* tant qu’il ya un élément de priorité pr, on le
supprime */
{ y.idP = x.id ;
strcpy ( y. user, x.username) ;
/* Ajouter l’élément à la file */
ENFILER (tete, queue, y) ;
}
}

typedef struct { int priorite ; file *lien ; }st;


typedef struct eltpile { st infopile ; struct eltpile * suivant ; }pile ;

4. void main ( )
{ pile *S; st x ; liste *T; int n, pr;
/* on suppose que la liste est déjà créée */
Initpile (&S) ;
printf (“ donnez la valeur de priorité maximum”);
scanf (“%d”, &n);
for (pr = n; pr >=1; pr- - )
{ x.id = i;
/* on construit la file de priorité pr */
CONSTFILE ( &T, &tete, &queue,pr);
x.lien = tete;
empiler (&S, x);

17 S. BOUKHEDOUMA
Exercice 10

Partie I

typedef struct elt {int numbloc; struct elt * svt ; }liste ;


3. void SUPPRIM (liste **L)
{ liste *p = *L; *L = *L ->svt ; free(p) ;}

4. void Insere (liste **L, int num)


{ liste *p, *q, *r ;
p = (liste *) malloc (sizeof (liste)) ;
p -> info = num;
if (*L ->numbloc > num) { p ->svt = *L; *L =p; }
else /*parcourir la liste pour chercher la position d’insertion */
for (q= *L; q != NULL && q->numbloc < num ; r = q, q= q->svt); // boucle vide
// à la sortie de la boucle
r->svt = p ; p->svt =q ;
}

5. liste *CREATLIST (liste **L, long t)


{ liste *tete = NULL; *q, *r ;
while (t >0)
{ Insere (&tete, *L->numbloc); // prendre le 1er bloc de la liste L
SUPPRIM (L); // supprimer le 1er bloc de la liste L
t = t – tbloc; }
return (tete) ;}

Partie II
typedef struct { char nom[20] ; long taille ; liste *lien }st ;
typedef struct elt1 { st info; struct elt1 * suivant; }LIST; // pour la liste T

1. void AJOUT (LIST **T, char *NP, long t, liste **L)


{LIST *p, *q;
liste *tete = CREATLIST (t, L); // créer la liste des blocs nécessaires au programme de taille
t
p = (LIST *) malloc (sizeof (LIST));
strcpy (p->info.nom, NP) ; p->info. Taille = t; p->info.lien = tete; p->suivant = NULL;
if (*T = = NULL) { *T = p ;}
else // parcourir la liste pour arriver au dernier élément
{for (q= *T; q -> suivant!= NULL ; q= q->suivant); // boucle vide
// à la sortie de la boucle q->svt =p ; }
}

2. void DELETE (LIST **T, char *NP, liste **L)


{ LIST *p = *T ;
if ( !strcmp (NP, *T->info.nom) ) // suppression en tête de liste T
{ *T = *T ->suivant ; free(p) ; } }
else
// chercher le nom de programme NP dans la liste T
for (p= *T; p != NULL && strcmp (NP, p->info.nom) ; q = p, p= p->svt); // boucle vide
// à la sortie de la boucle q->svt = p->svt ;
// supprimer tous les blocs occupés par le programme et les insérer dans la liste L

18 S. BOUKHEDOUMA
liste *tete = p->info.lien ;
while (tete !=NULL)
{ INSERE ( L, tete->numbloc);
SUPPRIM(&tete); }

free (p); // libérer l’élément p supprimé de la liste T


}

3. void main()
{typedef struct {char nom[20]; long taille;} str;
str v[20], LIST *T= NULL, *p; liste * L; int n, tmin, i;
// lecture du vecteur
scanf(“%d”, &n);
for (i =0 ; i<n ; i++) { gets (v[i].nom); scanf(“%ld”, & v[i].taille); }
for (i =0 ; i<n ; i++) AJOUT (&T, v[i].nom, v[i].taille, &L); // construction de la liste T
puts (“donnez la taille minimale”); scanf (“%ld”, &tmin);
for (p= T, p != NULL ; p = p->suivant) // suppression des éléments
if (p->info.taille <tmin) DELETE(&T, p->info.nom, &L) ;
}

Exercice 11
typedef struct elt1{int info1, struct elt1 *svt1;}pile1;
typedef struct {int nbre; int freq;}st; typedef struct elt2 { st info2, struct elt2 *svt2}
pile2;

pile2 *CONSTPILE (pile1 *P1)


{pile2 *P2; int x, nb; st y;
while (!pilevide(P1))
{Depiler (&P1, &x); nb =1;
while (!pilevide(P1))
{Depiler (&P1, &z);
if (z = = x) nb++; else Empiler (&R, z); }
y.nbre = x; y.freq = nb; Empiler (&P2, y);
while (!pilevide(P1)) {Depiler (&R, &x); Empiler (P1,x);}
}

void main()
{pile2 * P2, *R ; pile1 *P1,*S; int i; st x, max;
P2 = CONSTPILE (P1) ;
while (!pilevide(P2))
{Depiler (&P2, &max);
while (!pilevide(P2))
{Depiler (&P2, &x); if (x.nbre >max.nbre) { Empiler (&R, max); max = x;}
// à la sortie de la boucle on atrouvé le max
for (i = 1 ; i<= max.freq ; i++) Empiler (&S, max.nbre);
while (!pilevide(R)) {Depiler (&R, &x); Empiler (P2,x);}
}

19 S. BOUKHEDOUMA
Exercice 12
typedef struct {int jour, mois, annee ;}dat ;
typedef struct {char nom[20] ; long taille ; dat datmodif}st ;
typedef struct elt {st info ; struct elt *svt ; }liste;

1/ int Existe (liste *T, char *nomfich)


{ liste *p ;
for (p=T ; p != NULL && strcmp(p->info.nom, nomfich)!=0; p = p->svt); // bcle vide
/*à la sortie de la bcle*/ if (p == NULL) return(0) ; else return (1) ; }

2/ void Ajout (liste **T, st X)


{ liste *p, *q ;
if ( ! Existe (T, X.nom)) // vérifier que le nom de fichier n’existe pas
{ p = (liste *)malloc (sizeof(liste)) ; p->info = X; p->svt = NULL;
If (*T = = NULL) // la liste est vide
*T = p ;
else // aller à la fin de la liste et faire le chaînage avec le dernier
{ for (q=*T ; q->svt != NULL; q = q->svt); // bcle vide
q->svt = p ; }
}
else puts(“le nom de fichier existe déjà”) ; }

3/ void Permute (liste *p, liste *q)


{ st X ; /* déclarer une variable intermédiaire*/ X = p->info ; p->info = q->info ; q-
>info = X ; }

4/ void Trier (liste *T) // on utilise le tri par permutation comme pour un vecteur
{ liste *p, *q ;
for (p=T ; p ->svt != NULL; p = p->svt)
for (q = p->svt, q!= NULL; q = q->svt)
if (strcmp (p->info.nom, q->info.nom) > 0 ) // on compare les noms et on permute
Permute (p, q) ; // appel de la fonction permute
}

5/ long Espace_Occ (liste *T) // il s’agit de faire la somme des tailles de fichiers
{liste *p ; long E = 0 ;
for (p=T ; p != NULL; p = p->svt) {E = E + p ->info.taille;} return (E); }

6/ void main()
{ liste *T, *p, *q ; st X ; dat d ; long E, EO; // Espace total et espace occupé
printf (“donnez la description du fichier à ajouter”); gets (X.nom) ;
scanf (“%ld”, &X.taille) ;
scanf (“%d%d%d”, &X.datmodif.jour, &X.datmodif.mois, &X.datmodif.année) ;
Ajout (&T, X) ;
Trier (T) // tri de la liste par ordre croissant des noms de fichiers
// affichage
printf (“les éléments de la liste sont ”);
for (p=T ; p != NULL; p = p->svt)
{ X = p->info; puts (X.nom); printf (“ %ld ”, X.taille) ;
printf (“%d %d %d \n ”, X.datmodif.jour, X.datmodif.mois, X.datmodif.année) ;
}
// calcul de l’espace
printf (“donnez l’espace total du support ”);scanf (“%ld”, E);
20 S. BOUKHEDOUMA
printf (“l’espace occupé est %ld ” , EO); printf (“l’espace libre est %ld ” , E- EO);}

Examen du module ALGO2 2012/2013

Exercice 1 (3pts)
Soient les fonctions mathématiques suivantes (prédéfinies en C dans la librairie <math.h> ) :
sin, cos, tan, acos, asin, atan, exp, log, log10, sqrt. Chacune de ces fonctions admet un
paramètre de type double et retourne un résultat de type double, par exemple la fonction sin a
le prototype suivant: double sin (double);
1. Ecrire un programme qui fait l’appel par pointeur de ces fonctions prédéfinies, selon le choix
(un numéro de 1 à 10) donné par l’utilisateur (1 : sin 2 : cos 3 : tan … 10: sqrt). On pourra
utiliser un vecteur de pointeurs.

Exercice 2 (5 pts)
1. Soit une pile P de mots (chaque élément de la pile est une chaine de caractères). Ecrire une
fonction Minimum qui renvoie la plus petite chaine (selon l’ordre du dictionnaire) contenue
dans la pile. La fonction doit supprimer cette plus petite chaine.
2. Etant donnée une pile P de mots (supposée créée). En utilisant la fonction précédente, écrire
un programme qui construit à partir de P, une pile S triée dans l’ordre décroissant (le
maximum au sommet).

NB : Il faudra donner la déclaration de la pile. Les primitives de manipulation de la pile


sont supposées prédéfinies.

Exercice 3 (12 pts)


On suppose qu’on a un ensemble de processus (programmes) devant s’exécuter sur la même
machine (avec un seul processeur). Chaque processus est décrit par un identificateur (id)
entier, une durée totale d’exécution (durée) de type entier long et le temps d’exécution restant
(tps restant) de type entier long.
1. Donner la déclaration de la structure St d’un processus.

Les processus considérés doivent s’exécuter par parties, à tour de rôle selon un quantum de
temps t fixe (c'est-à-dire une durée t fixe). Par exemple si le quantum t est égal à 200 unités et
le temps d’exécution du processus est égal à 1000 unités. Le processus devra être repris 5 fois
pour exécution.
Pour gérer l’exécution de ces processus, on les range dans une liste chaînée circulaire de point
d’entrée tête.
Tete id1 Durée1 Tps id2 Durée2 Tps id3 Durée3 Tps
restant1 restant2 … restant 3

2. Donner la déclaration de la liste.


3. Ecrire une fonction Affiche qui affiche les éléments de la liste.
4. Ecrire une fonction PlusCourt qui cherche le processus le plus court (en temps d’exécution)
de la liste et retourne son numéro (id).

Le premier processus qui passe à l’exécution est celui qui se trouve en tête de liste. Ainsi, il
s’exécute pendant un quantum t donné et le temps restant est mis à jour. Si le temps restant
n’est pas nul, le processus est remis à la fin de la liste sinon il est supprimé de la liste.
5. Ecrire une fonction Supprime qui supprime le premier élément d’une liste circulaire de
processus de point d’entrée tete.
6. Ecrire une fonction Deplace qui déplace le processus de tête vers la fin de la liste circulaire.

21 S. BOUKHEDOUMA
7. En utilisant les fonctions Deplace et Supprime, écrire une fonction Execute qui simule
l’exécution du processus qui se trouve en tête de liste pendant un quantum de temps t donné (il
s’agit de mettre à jour le temps restant du processus et de mettre à jour l’état de la liste).

8. On suppose que la liste circulaire de processus est créée. Ecrire un programme qui cherche le
processus le plus court de la liste et simule l’exécution des processus (selon un quantum de
temps t) jusqu’à arriver au processus le plus court. Le programme doit afficher la liste à la fin.
9. Reprendre la question précédente pour simuler l’exécution complète de tous les processus de
la liste.

22 S. BOUKHEDOUMA