Vous êtes sur la page 1sur 258

Universit Galatasaray

Facult dingnierie et de technologie

Algorithmique &
programmation en langage C
Damien Berthet & Vincent Labatut

Sujets de travaux pratiques


Supports de cours Volume 2
Priode 2005-2014

Damien Berthet & Vincent Labatut 2005-2014


Damien Berthet & Vincent Labatut 2005-2014
Ce document est sous licence Creative Commons Attribution - Pas dUtilisation Commerciale Partage dans les Mmes Conditions 4.0 International. Pour accder une copie de cette licence, merci
de vous rendre l'adresse suivante :
http://creativecommons.org/licenses/by-nc-sa/4.0/
Galatasaray Universitesi
Mhendislik ve Teknoloji Fakltesi
raan Cad. No:36
Ortaky 34349, stanbul
Turquie

version 1
23/07/2014

Sommaire
SOMMAIRE
1

INFORMATIONS PRATIQUES
1.1
1.2

CONVENTIONS
ACCS AUX RESSOURCES

INSTALLATION ET CONFIGURATION
2.1
JAVA
2.1.1
Windows
2.1.2
Linux
2.1.3
Vrification
2.2
ECLIPSE
2.2.1
Installation
2.2.2
Utilisation
2.3
CDT
2.3.1
Compilateur C
2.3.2
C/C++ Development Tooling
2.3.3
Test de linstallation
2.3.4
Problmes possibles
2.4
SDL
2.4.1
Installation
2.4.2
Configuration
2.4.3
Test de linstallation
2.4.4
Problmes possibles

UTILISATION EN TP
3.1
RGLES CONCERNANT LES TP
3.1.1
Nommage
3.1.2
Programmation
3.1.3
Texte
3.1.4
Remise du travail
3.2
CRATION DUN PROJET
3.2.1
Nom du projet
3.2.2
Structure du projet
3.2.3
Importation de fichiers
3.3
BIBLIOTHQUE MATHMATIQUE
3.4
COMPILATION
3.5
EXCUTION
3.5.1
Dans Eclipse
3.5.2
Hors dEclipse
3.6
DBOGAGE
3.6.1
Perspective de dbogage
3.6.2
Contrle de lexcution
3.6.3
Accs la mmoire

SUJETS DE TP
01
02
03
04
05
06
07
08
09

ENTRES-SORTIES
TYPES SIMPLES
VARIABLES & OPRATEURS
INSTRUCTIONS DE CONTRLE
CRIBLE D'RATHOSTNE
CHANES DE CARACTRES
TABLEAUX MULTIDIMENSIONNELS
DIAGRAMMES TEXTUELS
INTRODUCTION LA SDL

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

MODIFICATION DES COULEURS


PASSAGE DE PARAMTRES
ALGORITHME DE BRESENHAM
HISTOGRAMME DES COULEURS
PROPRITS ARITHMTIQUES
ALGORITHMES POUR L'ARITHMTIQUE
BIBLIOTHQUE CHANE
DCOMPOSITION D'UNE PERMUTATION
NOMBRES BINAIRES
ALGORITHME DE JOHNSON
MANIPULATION DE DATES
CARRS LATINS
REPRSENTATION D'UNE PROMOTION
PARTITION D'UN ENTIER
ROTATION D'UN CARR
ZOOM D'UNE IMAGE
AUTOMATES FINIS
CHAMPIONNAT DE FOOTBALL
FLOUTAGE D'UNE IMAGE
FLOUS AVANCS
GESTION D'UN LEXIQUE
ALLOCATION DYNAMIQUE
GNRATEUR PSEUDO-ALATOIRE
NOMBRES HEXADCIMAUX
AGENDA TLPHONIQUE
FICHIERS ET ARGUMENTS DE PROGRAMME
DIAPORAMA
STOCK D'UNE LIBRAIRIE
AUTOMATES CELLULAIRES
FONCTIONS RCURSIVES
APPROXIMATIONS NUMRIQUES
FIGURES FRACTALES
LISTES CHANES
DISQUES & GUIRLANDES
LISTES DE CARACTRES
TAPIS DE SIERPISKI
SUITE DE SYRACUSE
ENVELOPPE D'UN NUAGE DE POINTS
MARCHES DE GRAHAM & JARVIS
ANALYSE D'EXPRESSIONS
CONVERSION D'EXPRESSIONS
DTECTION DE PALINDROMES
TOURS DE HANO
REMPLISSAGE DE FORMES
PARCOURS D'UN LABYRINTHE
GNRATION D'UN LABYRINTHE
TRI PAR DNOMBREMENT
TRI COCKTAIL
REPRSENTATION DES TRIS
TRIS SUR LISTES
REPRSENTATION DE L'ADN
NOMBRES DE GRANDE TAILLE
TABLE DE SYMBOLES
PLUS LONGUE SOUS-SQUENCE COMMUNE
ARBRES BINAIRES

Ce document regroupe 64 sujets de travaux pratiques (TP) et dexamen, crits pour


diffrents enseignements dalgorithmique et de programmation en langage C donns la
Facult dingnierie de lUniversit Galatasaray (Istanbul, Turquie), entre 2005 et 2014. Il
sagit du deuxime volume dune srie de 3 documents, comprenant galement le support de
cours (volume 1) et un recueil des corrigs de ces sujets (volume 3).
Les sujets dexamen ont t retravaills pour prendre la forme de sujets de TP. Les 64
sujets proposs ont t ordonns de manire correspondre la progression des concepts
paralllement tudis en cours (cf. le volume 1). En ce qui concerne les concepts les plus
simples, il est difficile de sortir des exercices assez classiques, dautant plus que les tudiants
ne disposent ce moment-l du cours que dun bagage technique trs rduit. Cependant, nous
avons tent daborder des thmes plus originaux dans les sujets venant plus tard. Nous nous
sommes particulirement attachs proposer des exercices bass sur une approche graphique
de lalgorithmique, grce lutilisation de la bibliothque SDL1 (Simple DirectMedia Layer).
Le volume horaire dun (ou mme de deux) cours classique(s) ne permet bien entendu pas
deffectuer tous les TP proposs ici. Il faut remarquer que si certains sujets introduisent un
concept nouveau, dautres, au contraire, se concentrent sur lapprofondissement dune ou
plusieurs notions dj utilises. Lide est plutt, pour lenseignant, de disposer dun
assortiment dexercices divers, dans lequel il peut choisir ce dont il a besoin, en fonction des
tudiants, de la progression effective et des objectifs de son cours. Pour les tudiants, il sagit
de proposer des exercices pouvant offrir une vision alternative celle donne dans le cours
suivi, ou bien dapprofondir certains points vus en cours.
Malgr tout le soin apport la rdaction de ces sujets, il est probable que des erreurs sy
soient glisses. Merci de nous contacter afin de nous indiquer tout problme dtect dans ce
document. Il faut galement remarquer quil sagit de TP donns dans le cadre dun cours
dintroduction, aussi les notions abordes le sont parfois de faon simplifie et/ou incomplte.
Le reste du document est organis de la faon suivante. Nous prsentons dabord les
conventions adoptes dans les sujets. Puis, nous dcrivons les outils utiliss au cours des TP,
savoir GCC2 pour la compilation, Eclipse3 pour lenvironnement de programmation, et la
SDL pour la manipulation des graphismes. Nous expliquons comment les installer et donnons
les rudiments de leur utilisation. Nous donnons ensuite une liste synthtique des sujets, en
prcisant notamment comment ils utilisent les diffrentes notions vues en cours. Enfin, le
cur du document est constitu des sujets de TP eux-mmes.
Damien Berthet & Vincent Labatut
le 7 juillet 2014

https://www.libsdl.org/
http://gcc.gnu.org/
3
http://www.eclipse.org/
2

Supports de cours vol.2 Priode 2005-2014

1 Informations pratiques
1.1 Conventions
Afin de faciliter la comprhension des sujets, certaines conventions de mise en forme sont
systmatiquement employes dans les trois volumes.
Tout dabord, les identificateurs (noms de fonctions, variables, constantes, etc.) sont
indiqus en utilisant la police Courier.
La plupart des exercices consistent crire une fonction implmentant un traitement
demand. Nous essayons, dans la mesure du possible, de toujours donner un exemple de ce
traitement. Quand celui-ci implique une interaction avec lutilisateur (affichage ou saisie), le
contenu de la console est reprsent en utilisant Courier sur fond bleu. Lorsque lutilisateur
doit saisir des valeurs, celles-ci sont surlignes en jaune.
Entrez une valeur : 12
Vous avez entr la valeur 12.

Lorsque du code source est cit, nous employons un fond rouge. Si une partie du code
source en particulier doit tre dsigne, elle est surligne en vert.
int ma_function(int x)
{ int une_variable_notable;
...

1.2 Accs aux ressources


Certains sujets ncessitent dutiliser/complter des bibliothques, ou bien daccder des
images. Ces donnes additionnelles sont disponibles partir de la page du cours sur
Kikencere4. La remise du travail se fait galement sur Kikencere.

http://kikencere.gsu.edu.tr/

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

2 Installation et configuration
Dans cette section, nous expliquons brivement comment installer et configurer les
diffrents outils utiliss en TP, savoir :
Lenvironnement dexcution de Java, qui est ncessaire pour utiliser Eclipse ;
Le logiciel Eclipse, qui sera notre environnement de programmation ;
Un compilateur capable de traiter des programmes crits en langage C ;
La bibliothque SDL que nous utiliserons pour dessiner lcran.
Notez que tous ces outils sont libres dutilisation, et multiplateforme. Ils sont disponibles
au moins pour les systmes Windows, Unix/Linux et Apple. Cependant, dans nos
explications, nous ne traitons que les deux premiers.
Chaque tape dcrite ici suppose que ltape prcdente a t ralise avec succs. Inutile
de passer ltape suivante tant que ltape courante nest pas valide. Par exemple, ne tentez
pas dinstaller Eclipse tant que vous ne russissez pas faire fonctionner Java dabord.

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

2.1 Java
Java est la fois un langage de programmation et un environnement
dexcution, dvelopps par Sun Microsystems partir de 1995, puis
Oracle depuis 2010. Le langage est orient objet, et lenvironnement
dexcution permet de crer des programmes de faon relativement
indpendante de la plateforme.

2.1.1 Windows

Allez sur le site de Sun Microsystems consacr Java :


http://java.sun.com/javase/downloads/index.jsp
Tlchargez le dernier JDK (Java Standard Edition Development Kit) version SE
(Standard Edition) pour Windows.
Installez le JDK en excutant le programme que vous venez de tlcharger.
On notera dornavant <Java> le dossier dinstallation du JDK.

2.1.2 Linux

La plupart du temps, Java est dj install sous Linux (cela dpend de la


distribution que vous utilisez).
Vrifiez que :
o Cest bien le JDK entier qui est install, et non pas seulement le JRE (Java
Runtime Environment).
o Il sagit bien de la dernire version disponible du JDK.
Dans le cas contraire, vous devez installer le dernier JDK.
Remarque : vous aurez gnralement besoin dtre connect en tant
quadministrateur.
La procdure dinstallation dpend de la distribution Linux que vous utilisez :
o Ubuntu : vous pouvez utiliser le gestionnaire de packages Synaptic.
o Fedora : vous pouvez utiliser le gestionnaire de packages Yellow Dog.
Si vous ne pouvez pas utiliser de gestionnaire de packages, il faut raliser la
procdure manuellement :
o Allez sur le site de Sun Microsystems consacr Java :
http://java.sun.com/javase/downloads/index.jsp
o Tlchargez le dernier JDK (Java Standard Edition Development Kit)
version SE (Standard Edition) pour Linux.
o Dplacez larchive auto-extractible dans le dossier o vous voulez installer
Java, par exemple : /usr/local.
o On notera dornavant <Java> ce dossier dinstallation.
o Ouvrez un terminal OS (galement appel console) et rendez-vous dans
<Java>, puis entrez les commandes :

> chmod +x jdk-<version>-linux-i586.bin


> ./jdk-<version>-linux-i586.bin

o Vous devez bien sr remplacer <version> par la version du JDK que vous
tes en train dinstaller.
o La licence dutilisation va tre affiche, tapez yes la fin pour laccepter.
o Pour terminer linstallation, vous devez ensuite modifier et crer certaines
variables denvironnement :

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

Ouvrez votre fichier profil situ dans le dossier $HOME5 : il sagit


gnralement dun fichier appel .profile ou .bashrc.
la fin de ce fichier, rajoutez les lignes suivantes (en remplaant
les lments entre '<' et '>' par les valeurs relles) :

JAVA_HOME=<Java>/jdk<version>
export JAVA_HOME
CLASSPATH=.
export CLASSPATH
PATH=$JAVA_HOME/bin:$PATH
export PATH

Enregistrez le fichier, dconnectez-vous, et connectez-vous sur le


compte dont vous venez de modifier le profil.

2.1.3 Vrification

Vrifiez que Java est bien install :


o Ouvrez un terminal OS.
o Entrez la commande :

> java -version

o Vous devez obtenir une rponse indiquant la version du JRE.


o Entrez ensuite la commande :
> javac -version

o Vous devez obtenir une rponse indiquant la version du JDK.

Rappel : sous Unix ou Linux, $HOME reprsente le dossier personnel de lutilisateur, i.e. :
o <utilisateur> est lidentifiant de lutilisateur.

/home/<utilisateur>

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

2.2 Eclipse
Eclipse est un environnement de dveloppement intgr
(IDE) libre (open source), dvelopp au sein dune fondation
rassemblant des acteurs importants du domaine, que ce soit des
entreprises (IBM, Intel, Nokia, Google) ou des institutions
(universits, associations de promotion de lopen source).
Initialement, Eclipse permet de programmer en Java, mais
il est possible dinstaller des extensions permettant dutiliser
dautres langages.
Remarque : avant dinstaller Eclipse, il est absolument ncessaire que vous vous assuriez
que Java est correctement install (cf. la section 2.1, dcrivant linstallation de Java).

2.2.1 Installation
2.2.1.1 Windows
Connectez-vous au site officiel dEclipse : http://www.eclipse.org.
Tlchargez le dernier SDK (Standard Development Kit) version classique pour
Windows.
Attention : pour viter dventuels problmes, vous devez installer Eclipse dans
un dossier dont le chemin ne comporte pas de caractre espace (' ').
Crez un dossier c:\Eclipse qui sera utilis pour linstallation dEclipse.
Ce dossier sera dornavant dsign sous le nom <Eclipse>.
Dcompressez larchive dans le dossier <Eclipse>, de manire ce que
lexcutable eclipse.exe se trouve directement dans <Eclipse>.
2.2.1.2 Linux
Comme pour Java, certaines distributions (Ubuntu par exemple) incluent Eclipse :
o Il suffit alors dutiliser le gestionnaire de package (Synaptic ou Yellow
Dog) pour installer Eclipse.
o Vrifiez bien quil sagit de la dernire version dEclipse disponible.
Si vous ne disposez pas de gestionnaire de package :
o Connectez-vous au site officiel dEclipse : http://www.eclipse.org.
o Tlchargez le dernier SDK1 (Standard Development Kit) version classique
pour Linux.
o Crez un dossier eclipse dans votre dossier personnel $HOME6.
o Ce dossier dinstallation dEclipse $HOME/eclipse sera dornavant
dsign sous le nom <Eclipse>.
o Dcompressez larchive dans le dossier <Eclipse>, de manire ce que
lexcutable eclipse se trouve directement dans <Eclipse>.
Par votre confort dutilisation, vous pouvez crer un raccourci qui vous permettra
de lancer facilement Eclipse. Par exemple, sous la GUI Gnome :
o Faites un clic-droit sur le menu horizontal situ tout en haut du bureau.
o Choisissez Add to panel.
o Slectionnez Custom application launcher puis cliquez sur Add.
o Remplissez les champs :

Cf. linstallation de Java, section 0.

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

Name : Eclipse
Command : <Eclipse>/eclipse
Icon : <Eclipse>/icon.xpm

2.2.2 Utilisation
2.2.2.1 Espace de travail
Un espace de travail est un dossier destin contenir tous vos programmes
concernant un projet ou un ensemble de projets lis. Un mme utilisateur a en
gnral besoin de plusieurs espaces de travail diffrents.
Crez un dossier <Eclipse>/workspaces qui contiendra tous vos espaces de
travail.
Attention : le chemin de ce dossier ne doit surtout pas contenir de caractres
espace (' ').
Lancez Eclipse grce lexcutable situ dans <Eclipse> ou au raccourci que
vous avez cr.
Au dmarrage, Eclipse vous demande dindiquer votre Workspace (espace de
travail) : indiquez <Eclipse>/workspaces/INFxxx o INFxxx dsigne le cours
concern (par exemple INF202 pour le cours dalgorithmique et programmation
II).

Attention :
o Si vous cochez la case Use this as the default and do not ask again, Eclipse
ne vous demandera plus de choisir votre espace de travail au dmarrage.
o Il ne faut donc surtout pas cocher cette case.
o Si vous cochez accidentellement cette case, vous pouvez rtablir loption
dans Eclipse en allant dans Windows>Preferences>General>Startup and
Shutdown>Prompt for workspace at startup.
Il est possible de changer lespace de travail courant depuis Eclipse en utilisant
File>Switch Workspace.

2.2.2.2 Perspective
Eclipse est dcompos en diffrentes fentres qui offrent laccs diffrentes
informations. Par dfaut, on peut observer :
o Le code source au centre.
o Le navigateur de projet gauche.
o Le navigateur de classe droite.
o La console et diffrentes informations en bas.

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

On appelle perspective la faon dont les diffrentes fentres dEclipse sont


organises. La perspective par dfaut est la perspective Java, adapte ce langage
de programmation.
Mais Eclipse est un environnement ouvert, et il est possible de manipuler dautres
langages, en installant au pralable des extensions tlchargeables. Une
Perspective diffrente peut tre utilise pour chaque langage.
Mais il est galement possible de changer de perspective en fonction de son
activit. Par exemple, la perspective par dfaut est une perspective ddie la
programmation. Pour passer une perspective ddie au dboguage, il suffit
dutiliser le menu situ en haut droite de la fentre principale.

2.2.2.3 Autres fonctionnalits


Pour avoir un aperu des diffrentes fonctionnalits dEclipse, rfrez-vous aux
nombreux tutoriels disponibles sur le Web, comme par exemple :
o http://help.eclipse.org/help32/index.jsp
o http://eclipsetutorial.forge.os4os.org/in2.htm
o http://www.eclipsetotale.com/articles/premierPas.html
o http://jmdoudoux.developpez.com/java/eclipse/

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

2.3 CDT
CDT (C/C++ Development Tooling) est une extension pour Eclipse
dveloppe par la fondation Eclipse. Il sagit dun outil libre, mais
professionnel, utilis dans lindustrie. Pour lutiliser, il faut disposer
dEclipse et dun compilateur C.

2.3.1 Compilateur C
Le compilateur C que nous allons utiliser pour programmer en C est
gcc, qui a t dvelopp pour Unix/Linux par GNU. Gnralement, sous Linux ce compilateur
est install par dfaut. Si ce nest pas le cas, utilisez votre gestionnaire de package (par
exemple Synaptic pour Ubuntu) pour linstaller.
2.3.1.1 Tlchargement
Sous Windows, il est ncessaire dinstaller MinGW (collection doutils permettant
dutiliser sous Windows des logiciels originalement dvelopps pour Unix/Linux), MSys
(compltant MinGW) et gdb (charg du dbogage). Les outils MSys et gdb sont maintenant
inclus dans le package de MinGW, donc vous aurez seulement besoin de tlcharger MinGW.
Pour cela :
Allez sur la page Sourceforge de MinGW, qui est situe ladresse
http://sourceforge.net/project/showfiles.php?group_id=2435
Tlchargez la dernire version stable.
2.3.1.2 Installation de MinGW
Dclenchez linstallation de MinGW, de manire faire apparatre la fentre
suivante :

Indiquez

un

dossier

dinstallation, de prfrence dans Eclipse :


. Ce dossier sera dornavant not <MinGW>.
Pour les autres options, vous pouvez garder les valeurs par dfaut. Cliquez ensuite
sur Continue : le programme va charger les donnes ncessaires linstallation.
Une fois ce chargement termin, cliquez nouveau sur Continue.
<Eclipse>7\tools\MinGW

Dossier dinstallation dEclipse, cf. la section 2.2 sur linstallation dEclipse.

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

Un gestionnaire dinstallation similaire celui-ci-dessous va alors souvrir.


Slectionnez uniquement les packages suivants (les autres sont inutiles pour nos
TP de C) :
o mingw32-base : compilateur et dboguer ;
o msys-base : MSys.

Cliquez sur Installation > Apply Changes, et la fentre suivante va souvrir :

Cliquez sur le bouton Apply pour poursuivre linstallation.


Fermez la fentre une fois linstallation termine, puis le gestionnaire
dinstallation.

2.3.2 C/C++ Development Tooling


2.3.2.1 Installation
Pour installer lextension CDT (sous Windows et Linux), lancez dabord Eclipse.
Remarque : on suppose dans ce document que vous avez install la toute dernire
version dEclipse.
Cliquez sur Help> Install New Software.
o Choisissez tous les sites disponibles
o Cochez Programming languages puis C/C++ Development
o Cliquez sur Next

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

Cliquez nouveau sur Next.


Acceptez la licence puis cliquez sur Finish.
Eclipse va tlcharger lextension, puis linstaller (il vous sera ventuellement
demand de valider linstallation).
Aprs linstallation de CDT, il est possible que vous deviez redmarrer Eclipse.

2.3.2.2 Configuration
Aprs le redmarrage dEclipse, allez dans Window>Preferences :
o Enregistrement automatique la compilation : dans C/C++>New CDT
project wizard>Makefile project>Behaviour, cochez la case Build on
resource save (Auto build).
o Dsactiver le correcteur orthographique : dans General>Editors>Text
Editors>Spelling, dcochez Enabled spell checking.
La dernire tape concerne seulement les utilisateurs de Windows, elle consiste
vrifier que les chemins de MinGW, MSys et gdb sont bien prsents dans la
variable denvironnement PATH :
o Allez dans Window > Preferences > C/C++ > Build > Build variables et
cliquez sur Show system variables (en bas gauche).
o Cherchez la variable PATH et cliquez sur Edit.

o Dans

Value, vrifiez
que
les
chemins
<MinGW>\bin
<MinGW>\msys\1.0\bin sont biens prsents (sinon rajoutez-les).

o Cliquez sur OK (deux fois).

Sujets de travaux pratiques

et

Supports de cours vol.2 Priode 2005-2014

2.3.3 Test de linstallation


Pour vrifier si la CDT a t bien installe, crez, compilez et excutez un programme C :
Placez-vous dans la perspective C/C++
Cliquez sur File > New > C Project (et non pas C++ Project, attention !)
Une fentre apparait :
o Project name : donnez un nom votre projet (par exemple : Test).
o Project type : slectionnez Executable > Hello World ANSI C Project.
o Cliquez sur le bouton Finish.
Compilez le projet : Project > Build Project. En cas de problme, un message
derreur apparatra dans la console dEclipse.
Excutez le programme : faites un clic-droit sur le projet (dans Project Explorer),
puis Run As > Local C/C++ Application.
Le texte !!!Hello World!!! Devrait apparatre dans la console. Sinon, cest
quil y a un problme dinstallation.

2.3.4 Problmes possibles

gcc not found ou make not found :

o Ce message est affich lorsque le chemin vers MinGW et MSys nest pas
correctement configur : vrifiez donc dabord quil est valide.
o Certaines versions dEclipse ont aussi des problmes avec les chemins
dfinis en interne. Il est alors possible de les dfinir en externe, i.e. dans
Windows :
Ouvrez les proprits du systme :
Windows XP (et versions plus anciennes) :
o Sur le bureau, faites un clic-droit sur le Poste de
travail.
o Cliquez sur Proprits, puis sur longlet Avanc.
Windows Vista (et versions plus rcentes) :
o Allez dans le menu Dmarrer, puis ouvrez le
Panneau de configuration.
o Cliquez sur Systme, puis Paramtres systme
avancs (lien situ gauche).

La fentre Proprits systme ci-dessus apparait alors.

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

Cliquez sur le bouton Variables denvironnement : une nouvelle


fentre judicieusement appele Variables denvironnement va alors
apparatre.
Dans la partie Variables systme, slectionnez Path puis cliquez sur
le bouton Modifier
Rajoutez les deux chemins manquants (cf. section 2.3.2.2), la fin
des chemins dj prsents, en les sparant par des points-virgules
(;).
Cliquez 3 fois sur OK pour fermer ces fentres.
Redmarrez Windows pour appliquer les modifications.
Unresolved inclusion :
o Parfois, il est possible quEclipse affiche cet avertissement quand vous
incluez des bibliothques frquemment utilises. Cela nempche pas
lexcution du programme, mais si vous voulez quand mme supprimer
lavertissement :
Allez dans Project>Properties>C/C++ General>Paths and
Symbols.
Ajoutez le chemin <MinGW>\include Include directories.
Erreur de compilation sans message associ :
o Eclipse affiche parfois des erreurs de compilation au niveau du projet (par
opposition aux fichiers contenus dans le projet).
o Ces erreurs persistent lorsquon rafraichit le dossier et quon recompile.
o Aucun message derreur nest associ dans la console.
o Vous pouvez alors tenter de faire un clic-droit sur le projet dans
lexplorateur de dossier, puis Index>Rebuild.

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

2.4 SDL
Simple Directmedia Layer (SDL) est une bibliothque
opensource multiplateforme (Windows, Linux, MacOS)
permettant daccder des fonctionnalits multimdia
(graphismes, sons, contrle) depuis diffrents langages de
programmation, et en particulier depuis le langage C. Dans le
cadre de ce cours, nous utiliserons la SDL uniquement pour ses
fonctionnalits graphiques. Ce document explique la marche suivre pour utiliser la SDL
avec Eclipse et CDT.
Remarque : on suppose ici que vous avez respect la procdure des sections prcdentes
concernant linstallation de Java (2.1), Eclipse (2.2) et CDT (2.3).

2.4.1 Installation
2.4.1.1 Windows
Allez ladresse http://www.libsdl.org, puis cliquez sur la version 1.2 dans la
section Downloads.
Dans Development Libraries, tlchargez la dernire version pour MinGW (pour
Windows).
Dcompressez larchive SDL, et copiez les dossiers SDL\bin, SDL\include, et
SDL\lib dans le dossier <MinGW>8.
Remarque : attention de ne pas confondre <MinGW> et <MinGW>\mingw32.
2.4.1.2 Linux
La mthode dinstallation dpend de la distribution que vous utilisez, mais en rgle
gnrale il faudra disposer des droits dadministrateur.
Sous Ubuntu, la SDL est disponible partir du gestionnaire de packages Synaptic.
Sous Fedora, vous pouvez utiliser Yellow Dog Updater, en tapant dans une
console OS :
> yum install SDL-devel SDL_mixer-devel SDL_image-devel SDL_ttf-devel

Pour les autres distributions, vous pouvez consulter la page suivante, qui contient
quelques tutoriels concernant la SDL :
http://lazyfoo.net/SDL_tutorials/lesson01/linux/index.php

2.4.2 Configuration
Par rapport un projet textuel (nutilisant pas la SDL), il est ncessaire deffectuer
certains rglages supplmentaires afin que le compilateur trouve la SDL. Ces rglages
dpendent du systme dexploitation que vous utilisez.
2.4.2.1 Windows
Crez tout dabord un nouveau projet C.
Dans les proprits du projet, allez dans C/C++ Build>Settings>Tool
settings>MinGW C Linker>Libraries.

Dossier dinstallation de MinGW, cf. la section 2.3 sur linstallation de CDT.

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

Dans Libraries (-l) : rajoutez (en respectant imprativement cet ordre) les
bibliothques (simplement en entrant leurs noms) : mingw32, SDLmain et SDL.

2.4.2.2 Linux
Dans les proprits du projet, allez dans C/C++ Build>Settings>Tool
settings>GCC Linker>Libraries.
Dans Libraries (-l) : rajoutez SDL (simplement en entrant ce nom).

2.4.3 Test de linstallation


Afin de tester votre installation de la SDL, effectuez les actions suivantes :
Assurez-vous que la CDT est correctement configure, et quil est possible de
compiler et dexcuter un projet C classique (i.e. nutilisant pas la SDL).
Remarque : si vous ne savez pas comment faire, consultez la section 2.3 sur
linstallation de la CDT.
Crez un nouveau projet appel TestSDL.
Dans ce projet, crez un fichier main.c.
Dans ce fichier, copiez-collez le code source suivant :
#include <SDL\SDL.h>
int main(int argc, char** argv)
{ // cree la fenetre graphique
SDL_Init(SDL_INIT_VIDEO);
atexit(SDL_Quit);
SDL_SetVideoMode(200, 200, 32, SDL_SWSURFACE);
SDL_WM_SetCaption("Test SDL", NULL);
// attend une touche pour quitter
SDL_Event event;
do
{ SDL_WaitEvent(&event);
}
while(event.type != SDL_QUIT && event.type != SDL_KEYDOWN);
return 0;
}

Remarque : pour Linux, la premire ligne doit contenir un slash (/) la place du
backslash (\) utilis pour Windows.
Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

Compilez et excutez le projet.


Une petite fentre noire devrait alors apparatre.
Appuyez sur une touche pour la refermer.
Si le programme ne compile pas, ou si la fentre napparait pas, cest quil y a un
problme soit dans linstallation de la SDL, soit dans la configuration de votre
projet (en supposant que Java, Eclipse et la CDT soient correctement installs).

2.4.4 Problmes possibles


En fonction de votre configuration, il est possible que vous rencontriez diffrentes erreurs.
2.4.4.1 Erreur de compilation
Le compilateur naccde pas aux fichiers de la SDL.
Concrtement : dans le fichier qui importe la SDL, la ligne dimportation est
souligne en rouge.
Vrifiez que le caractre sparant SDL et sdl.h dans la ligne dimportation est
bien :
o pour Linux : '/' (slash).
o pour Windows : '\' (backslash).
Si ce nest pas la cause de lerreur, assurez-vous que vous avez scrupuleusement
respect la procdure dinstallation indique dans ce document : le problme vient
srement dun chemin (path) erron.
2.4.4.2 Erreur dexcution
Votre projet compile sans erreurs et la construction se termine normalement.
Mais quand vous lexcutez :
o sous Eclipse : rien ne se produit.
o sous la console de lOS : vous obtenez lerreur "SDL.dll est introuvable".
La cause de ce problme peut tre une mauvaise configuration de la variable
denvironnement PATH de votre OS. Pour Windows :
o Allez dans les Proprits du systme (Panneau de configuration>Systme).
o Slectionnez longlet Avanc puis cliquez sur Variables denvironnement.
o Dans Variables Systme, slectionnez Path et cliquez sur Modifier.
o Aprs les valeurs dj prsentes, rajoutez (sans aucun espace ' ' et sans
oublier le point-virgule ';') : ;<MinGW>\bin\.
o Remarque : vrifiez dabord si ce chemin nest pas dj inclus dans Path :
il ne sert rien de lajouter une deuxime fois.

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

3 Utilisation en TP
3.1 Rgles concernant les TP

Cette section contient un ensemble de rgles valables pour tous les TP et pour tous
les examens.
Si vous ne respectez pas ces rgles, votre travail ne sera pas corrig et vous aurez
la note zro.
Ces rgles sont toujours valables, sauf si le sujet ou lexercice le prcise
explicitement.

3.1.1 Nommage

Pour un TP, vous devez imprativement donner votre projet un nom de la forme
suivante : TPXX_NomPrnom.
o XX reprsente le numro du TP, par exemple : TP01 pour le premier TP (et
non pas TP1).
o Nom et Prnom reprsentent respectivement vos nom de famille et prnom.
Vous ne devez surtout pas utiliser de caractres turcs ni franais : pas
daccent, pas de cdille, etc. Par exemple, pour Can Emreolu, a sera
EmreogluCan.
o Donc pour son premier TP, Can Emreolu utilisera le nom
TP01_EmreogluCan.
Pour lexamen de TP, vous devez donner votre projet un nom de la forme
NomPrnom.
Quand des identificateurs (noms des fonctions, paramtres, constantes) sont
donns dans le sujet, vous devez utiliser les mmes noms dans vos programmes.

3.1.2 Programmation

Votre code source doit tre convenablement format et indent. Eclipse permet de
le faire automatiquement en faisant un clic-droit dans le code source et en
slectionnant Source>Format.
Votre travail ne doit contenir aucune erreur de compilation.
Vos fonctions doivent tre places :
o Si rien nest prcis : dans le fichier principal main.c.
o Si le sujet le prcise, dans une bibliothque particulire.
o Dans les deux cas, les fonction doivent tre places dans lordre des
exercices du TP : dabord la fonction de lexercice 1, puis celle de
lexercice 2, etc., et la fonction main la fin du programme.
Votre fonction main doit contenir le code ncessaire au test de chacune des autres
fonctions que vous avez crites :
o Chaque fonction doit tre appele avec des paramtres que vous aurez
dtermins lavance.
o Quand vous avez termin et test la fonction, vous devez placer lappel ou
(les appels) en commentaires avant de passer la fonction suivante.
o exemple : maFonction1 est termine, maFonction2 est en cours de
dveloppement :

int maFonction1(int parametre)


{ // traitement de la fonction
}

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

int maFonction2(char parametre1, int parametre2)


{ // traitement de la fonction
}
int main()
{ int x,resultat;
char c;
/*
// maFonction1
x = 0;
temp = maFonction1(x);
printf("maFonction1(%d)=%d\n",x,resultat);
x = -1;
temp = maFonction1(x);
printf("maFonction1(%d)=%d\n",x,resultat);
x = 255;
temp = maFonction1(x);
printf("maFonction1(%d)=%d\n",x,resultat);
*/
// maFonction2
...
}

o Le but est que les correcteurs puissent facilement tester votre travail.
Les bibliothques (listes, piles, files, etc.) ventuellement fournies avec un projet
ne doivent pas tre modifies.

3.1.3 Texte

Si la rponse un exercice prend la forme dun texte (et non pas dun
programme) :
o Vous devez crire cette rponse dans un fichier exerciceX.txt (pas de
document Word, Open Office, ou autre), X tant le numro de lexercice
concern.
o Ce fichier doit tre plac dans la racine du projet, et pas ailleurs.
Vous pouvez exceptionnellement utiliser du PDF, si jamais la question implique
de rendre des schmas.

3.1.4 Remise du travail

Vous devez rendre une archive au format ZIP ou RAR contenant votre travail.
Cette archive doit tre nomme comme votre projet.
Elle doit contenir le dossier correspondant votre projet Eclipse, c'est--dire le
dossier du type TPXX_NomPrnom contenu dans votre workspace.
o Attention de ne pas rendre un dossier contenant un dossier contenant... un
dossier contenant votre projet.
o Inversement, attention de ne pas rendre un sous-dossier de votre projet.
Vous devez rendre un projet Eclipse : ne rendez pas seulement une archive
contenant vos fichiers sources.
Vous ne devez pas rendre autre chose quun projet Eclipse : pas de DevC++ ou
autre.
Le travail qui vous est demand est un travail personnel : vous pouvez
ventuellement rflchir plusieurs sur un problme, mais la programmation est
individuelle.
Si plusieurs tudiants prsentent le mme travail, ils seront tous sanctionns. La
sanction peut aller jusqu la note zro pour tous les TP du semestre.

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

Toute copie partir des corrigs publis les annes prcdentes sera galement
sanctionne.

3.2 Cration dun projet


3.2.1 Nom du projet

Sous Eclipse, allez dans File>New>Project.


Allez dans C et slectionnez C Project.
Dans Project name, donnez un nom votre projet : cf. la section sur les rgles des
TP pour savoir quel nom vous devez donner votre projet.
Cliquez enfin sur Finish pour terminer la cration du projet, qui va alors apparatre
dans la fentre de gauche (appele Explorer).

3.2.2 Structure du projet

Le nom du dossier contenant votre programme sera identique celui de votre


projet.
Slectionnez le mode Executable et le Toolchain MinGW GCC, puis cliquez sur
Finish.

Perspective :
o Eclipse va ventuellement vous demander si vous voulez passer la
perspective C/C++, auquel cas il faut accepter.
o Une perspective est une faon dorganiser les outils dEclipse adapte un
langage de programmation donn.
o La perspective par dfaut est ddie Java.

3.2.3 Importation de fichiers

Dans certains TP, vous devrez utiliser des fichiers fournis avec le sujet, en gnral
sous la forme dune archive (souvent un fichier ZIP).
Pour pouvoir utiliser ces fichiers, vous devez les importer dans votre projet.
Bien sr, il faut dabord avoir cr votre projet (en respectant les rgles de
nommage nonces prcdemment).
Assurez-vous que votre projet est bien slectionn dans lexplorateur (fentre de
gauche), puis :
o Cliquez dans le menu File>Import puis sur General>Archive File, et enfin
sur Next.

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

o Utilisez le bouton Browse pour slectionner larchive importer.


o Une fois que larchive est choisie, son contenu va apparatre dans la partie
gauche de la fentre : cochez les cases correspondantes aux fichiers et/ou
dossiers que vous dsirez importer (en gnral : tous !).

o Cliquez sur le bouton Finish pour effectuer limportation.


o Remarque :
Si vous ne pouvez pas cliquer sur Finish, cest que vous navez pas
slectionn de projet avant de dmarrer limportation.
Vous devez alors utiliser le bouton Browse pour slectionner le
projet adquat.
Remarque : limportation copie toute la structure que vous slectionnez dans
larchive, y compris larborescence des dossiers, donc faites attention ce que
vous slectionnez.

3.3 Bibliothque mathmatique


Dans certains TP, il est ncessaire dutiliser diffrentes fonctions appartenant la
bibliothque mathmatique : valeur absolue, fonctions trigonomtriques, puissance, etc. Sous
Windows, il suffit dinclure cette bibliothque dans le programme, grce la directive :
#include <math.h>

En revanche, sous Linux, il faut aussi raliser cette inclusion mais elle ne suffit pas. Il est
ncessaire de spcifier que cette bibliothque est utilise, en plus, dans les proprits du
projet. Pour cela, il faut raliser les oprations suivantes :
Dans les proprits du projet, allez dans C/C++ Build>Settings>Tool
settings>GCC Linker>Libraries.
Dans Libraries (-l) : rajoutez m (juste cette lettre, en minuscule).

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

3.4 Compilation

Pour crer un fichier, effectuez un clic-droit sur le projet concern (dans la fentre
de gauche) et choisissez :
o New>Source File si vous voulez crer un fichier source (.c).
o New>Header File si vous voulez crer un fichier den-tte (.h)
Vous devez prciser le nom de votre fichier, y compris son extension (.c ou .h).
Par exemple : exo1.c.
Si vous avez configur Eclipse comme indiqu dans lannexe sur linstallation, la
compilation de votre fichier est ralise automatiquement chaque sauvegarde.
Sinon, il faut compiler manuellement en utilisant le bouton situ en haut, ou bien
en appuyant sur Control+B (pour Build).
La console dEclipse montre alors le rsultat de la construction de lexcutable :

3.5 Excution
3.5.1 Dans Eclipse

Si votre programme ne provoque pas derreur de compilation, vous pouvez


lexcuter depuis Eclipse, en utilisant la console dEclipse.
Dans la fentre de gauche, faites un clic-droit sur votre projet et choisissez Runs
as>Local C/C++ Application.
Une configuration dexcution est automatiquement cre, et lapplication est
excute dans la console dEclipse situe dans la fentre du bas.
Une configuration dexcution permet de paramtrer la faon dont un programme
est excut.
Si vous crez plusieurs configurations, elles apparatront dans le menu Run.

Une fois que la configuration dexcution est cre, il suffit de cliquer de nouveau
sur le bouton Run de la barre doutils pour r-excuter le mme programme avec
cette mme configuration.
Une configuration dexcution existante peut tre modifie en cliquant sur Open
Run Dialog dans le menu qui apparat sous le bouton Run.
En particulier, il est possible de spcifier des paramtres passer au programme
comme sil tait appel depuis la ligne de commande (console DOS ou Linux), en
utilisant longlet Arguments.

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

Lorsque vous lancez une configuration dexcution, votre programme est


automatiquement excut dans la console dEclipse.
Vous pouvez taper du texte dans la console si ncessaire, il apparatra dans une
autre couleur que le texte affich par le programme.

Attention : la console Eclipse nest pas buffrise de la mme faon que la


console systme : vous devez vider le buffer manuellement avec fflush pour
afficher le rsultat dune opration manipulant le flux standard de sortie (stdout).
exemple :
printf("blablabla");
fflush(stdout);

3.5.2 Hors dEclipse

Il est galement possible dexcuter un programme depuis la console systme, et


non pas depuis celle dEclipse :
o Ouvrez une console systme (sous Windows : Dmarrer>Programmes>
Accessoires>Invite de commandes).
o Allez dans le dossier correspondant votre projet (ex. : <Dossier
Personnel>\INF201\TP02).
o Allez dans le dossier appel Debug.
o Lancez le fichier excutable situ dans ce dossier (ici : TP02).

3.6 Dbogage
3.6.1 Perspective de dbogage

Le dbogage est un mode dexcution particulier, qui permet de rechercher des


erreurs dexcution :
o droulement dun programme pas pas.
o visualisation des valeurs des variables et de leur volution.
o possibilit de modifier leurs valeurs pendant lexcution.

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

Pour faire apparatre le bouton correspondant, cliquez sur le bouton Perspectives


dans la barre doutils ( droite) et slectionnez Debug.
Cette action va ouvrir la perspective de dbogage.
Revenez la perspective C/C++ en cliquant sur le bouton situ dans la barre
doutils ( ct de Debug) et ouvrez un programme existant.
Ouvrez le dialogue du menu Run pour modifier la configuration dexcution du
projet que vous voulez dbuguer.
Allez dans longlet Debugger et dsactivez loption Stop on startup at, qui dfinit
par dfaut un point darrt au niveau du main.

Cliquez sur Apply puis sur Close.


Repassez la perspective de dbogage.

3.6.2 Contrle de lexcution

Vous pouvez crer un point darrt dans votre programme en effectuant un double
clic-gauche dans la marge, au niveau de la ligne concerne. Le point darrt est
reprsent par un point bleu.

Pour lancer le dbogage, on procde comme pour lancer une excution : on utilise
une configuration dexcution.
La diffrence est quau lieu dutiliser le bouton dexcution, on utilise celui de
dbogage, qui est situ juste ct.

Lexcution a lieu dans une console systme (et non pas une console Eclipse).
Quand vous lancerez le dbogage, le programme sera excut jusqu votre point
darrt, puis sera mis en pause. La ligne courante est surligne dans la fentre
affichant le source du programme :

La fentre Debug situe en haut gauche est trs importante, elle affiche les
programmes en cours dexcution et affiche la pile des fonctions appeles.

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

Cette fentre dispose galement dune barre doutils permettant de contrler


lexcution :
o Resume (triangle vert) : reprend le cours normal de lexcution, jusqu ce
quun autre point darrt soit rencontr, ou bien jusqu la terminaison du
programme sil ny a pas dautre point darrt.
o Suspend (deux barres verticales) : permet de mettre manuellement un
programme en pause, par exemple lorsquil est pris dans une boucle infinie,
ce qui permet didentifier la boucle fautive.
o Terminate (carr rouge) : termine le programme.
o Step Into : excute la prochaine instruction. Si cette instruction est une
fonction, le dbogueur entre dans la fonction et permet lutilisateur de
contrler son excution.
o Step Over : excute la prochaine instruction. Sil sagit dune fonction, le
dbogueur excute la fonction normalement puis revient au mode
dexcution contrl par lutilisateur.
o Step Return : excute le reste de la fonction et repasse en mode contrl par
lutilisateur une fois la fonction termine.

3.6.3 Accs la mmoire

La fentre situe en haut droite permet daccder la mmoire du programme en


cours dexcution. En particulier, longlet Variables liste toutes les variables
existantes et donne accs leurs valeurs.
o Lexemple montre une variable nom, qui est une chane de caractres et
dont le contenu est quelconque car elle na pas t initialise.

o Les variables qui ont t modifies par linstruction qui vient dtre
excute (ici un scanf) apparaissent en jaune.

o Il est possible de modifier manuellement la valeur dune variable en


cliquant dans la colonne Value.

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

Une autre possibilit intressante est la possibilit dvaluer des expressions


pendant lexcution, en utilisant les valeurs courantes des variables :
o Si longlet Expressions napparat pas dans la fentre situe en haut
droite :
Cliquez sur longlet Variables.
Allez dans Window>Show View>Other.
Slectionnez Debug>Expressions puis cliquez sur OK.
Longlet Expressions devrait maintenant apparatre.
o Slectionnez longlet Expressions.
o Effectuez un clic droit dans le panel et cliquez sur Add Watch
Expression.

o Vous pouvez alors entrer lexpression valuer, en validant avec OK.

o Le panel de droite indique le rsultat de lvaluation de lexpression, ou


bien un message derreur si votre expression ne peut pas tre value.

Sujets de travaux pratiques

Supports de cours vol.2 Priode 2005-2014

4 Sujets de TP
Les sujets de TP sont rangs de manire suivre la progression du cours. Un TP donn se
concentre gnralement sur un nouveau point en particulier, mais il est susceptible dutiliser
les concepts manipuls dans les TP prcdents.
Le premier tableau suivant liste les TP en prcisant les concepts quils utilisent. Les
notions vraiment basiques, telles que la syntaxe du C, la structure dun programme, les
entres-sorties texte, les boucles et les fonctions, ne sont pas explicitement reprsentes car
elles sont utilises dans quasiment tous les TP (aprs leur TP dintroduction). Les notions
concernes sont dans lordre :
Lutilisation des tableaux,
Celle des chanes de caractres,
La cration de bibliothques spcifiques,
Lutilisation de la SDL (et donc de fonctions graphiques),
Lutilisation de pointeurs,
La dfinition et lutilisation de types numrs,
Celles de types structurs,
La lecture et lcriture dans des fichiers (autres que graphiques),
Lallocation dynamique de mmoire,
La dfinition de fonctions rcursives,
La manipulation de listes chanes (simplement et doublement),
Lutilisation de piles de donnes,
Celle de files de donnes,
Limplmentation dalgorithmes de tris,
Ltude de la complexit algorithmique.
Le second tableau liste les principaux prrequis pour chaque TP, i.e. les notions quil faut
avoir dj abordes pour pouvoir effectuer le TP. Il prcise aussi le(s) objectif(s) du TP. Ceux
indiqus en gras correspondent aux notions abordes pour la premire fois. De nombreux TP
ont pour but dapprofondir des concepts dj utiliss.

Sujets de travaux pratiques

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

Entres-sorties
Types simples
Variables & oprateurs
Structures de contrle
Crible d'rathostne
Chanes de caractres
Tableaux multidimensionnels
Diagrammes en mode texte
SDL & codage
Couleurs d'une image
Passage de paramtres
Algorithme de Bresenham
Histogramme des couleurs
Proprits arithmtiques
Algorithmes pour l'arithmtique
Bibliothque chaine
Dcomposition d'une permutation
Nombres binaires
Algorithme de Johnson
Manipulation de dates
Carrs latins
Reprsentation d'une promotion
Partition d'un entier
Rotation d'un carr
Zoom d'une image
Automates finis
Championnat de football
Floutage d'une image
Flous avancs
Gestion d'un lexique
Allocation dynamique
Gnrateur pseudo-alatoire
Nombres hexadcimaux
Rpertoire tlphonique
Fichiers & arguments de programme
Diaporama
Stock d'une librairie
Automates cellulaires
Fonctions rcursives
Approximations numriques
Figures fractales
Listes chanes
Disques & guirlandes
Listes de caractres
Tapis de Sierpiski
Suite de Syracuse
Enveloppe d'un nuage de points
Marches de Graham et Jarvis
Analyse d'expressions
Conversion d'expressions
Dtection de palindromes
Tours de Hano
Remplissage de formes
Parcours d'un labyrinthe
Gnration d'un labyrinthe
Tri par dnombrement
Tri cocktail
Reprsentation des tris
Tris sur listes
Reprsentation de l'ADN
Nombres de grande taille
Table de symboles
Plus longue sous squence commune
Arbres binaires

Complexit

Tris

Files

Piles

Listes

Rcursivit

Allocation

Fichiers

Structures

numrations

Pointeurs

SDL

Bibliothque

Chanes

Tableaux

Nom

Numro

Supports de cours vol.2 Priode 2005-2014

X
X
X
X
X
X

X
X

X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X

X
X
X

X
X
X
X

X
X
X
X
X

X
X

X
X

X
X
X
X

X
X
X
X
X
X

X
X

X
X
X
X

X
X
X

X
X
X

X
X
X

X
X

X
X

X
X

X
X

X
X
X

X
X
X
X

X
X

X
X
X

X
X

X
X
X
X

X
X

X
X

X
X
X

X
X

X
X
X

X
X
X
X
X

X
X
X
X
X

X
X

X
X

X
X
X
X

X
X
X
X
X
X
X
X
X
X
X

X
X
X

X
X
X
X
X

X
X

Liste des points abords dans chaque TP

Sujets de travaux pratiques

X
X
X
X

X
X

X
X
X
X
X
X

X
X
X
X
X

Supports de cours vol.2 Priode 2005-2014

N Nom

Prrequis principaux

Objectifs

01 Entres-sorties

Syntaxe du langage C

02 Types simples

08 Diagrammes en mode texte

crire une fonction principale


Afficher/saisir du texte
Notion de fonction
Oprateurs arithmtiques
Instructions conditionnelles/rptition
Faire un tableau de situation
Syntaxe des tableaux
Utiliser des boucles
Manipuler des tableaux
Syntaxe des chanes de caractres
Manipuler des tableaux
Utiliser des boucles
Syntaxe des fonctions
Utiliser des boucles

09 SDL & codage

Dfinir des fonctions

10 Couleurs d'une image

Utiliser la SDL
Codage des couleurs

11 Passage de paramtres

Utiliser la bibliothque mathmatique

12 Algorithme de Bresenham
13 Histogramme des couleurs

Utiliser la SDL
Notions de gomtrie
Utiliser la SDL
Charger une image

14 Proprits arithmtiques

Manipuler des tableaux

crire une fonction principale


Afficher/saisir du texte
Manipuler les types simples du C
Codage d'un nombre
Position des variables en mmoire
Valeur et type d'une expression
Utiliser les instructions conditionnelles
Utiliser les instructions de boucle
Manipuler des tableaux
Approfondir les boucles
Manipuler des chanes de caractres
Approfondir les tableaux
Manipuler des matrices
Tableaux multidimensionnels en mmoire
Dfinir des fonctions
Passer des paramtres
Crer/configurer un projet SDL
Dessiner des figures simples
Charger/afficher une image
Modifier une image
Approfondir les fonctions
Passer un paramtre par adresse
Tracer des segments
Approfondir la SDL
Crer une bibliothque
Rutiliser des fonctions existantes
Approfondir les tableaux
Approfondir le passage par adresse

03 Variables & oprateurs


04 Structures de contrle
05 Crible d'rathostne
06 Chanes de caractres
07 Tableaux multidimensionnels

21 Carrs latins

Dfinir des fonctions


Notions d'arithmtique
Syntaxe des chanes de caractres
ddd
Syntaxe des pointeurs
Crer une bibliothque
Syntaxe des pointeurs
Crer une bibliothque
Manipuler des pointeurs
Syntaxe des numrations
Dfinir de types personnaliss
Syntaxe des structures/numrations
Dfinir des types personnaliss
Dfinir des numrations
Manipuler des matrices

22 Reprsentation d'une promotion

Un peu tout ce qui a t vu prcdemment

Approfondissement gnral

23 Partition d'un entier

Approfondir les structures


Approfondir les pointeurs

24 Rotation d'un carr

Manipuler des structures


Manipuler des pointeurs
Manipuler des structures
Manipuler des matrices

25 Zoom d'une image

Manipuler des images

Approfondir les matrices

26 Automates finis
27 Championnat de football

Manipuler des structures


Manipuler des matrices
Manipuler des types personnaliss
Manipuler des matrices

28 Floutage d'une image

Manipuler des images

Approfondir structures
Notion d'automate fini
Approfondir les pointeurs
Approfondir les structures
Approfondissement gnral
Notion de floutage

29 Flous avancs

Floutage d'images
Manipuler des images
Manipuler des chanes de caractres
Manipuler des pointeurs
Manipuler des pointeurs
Manipuler des tableaux
Allocation dynamique
Bibliothque histogramme

15 Algorithmes pour l'arithmtique


16 Bibliothque chaine
17 Dcomposition d'une permutation
18 Nombres binaires
19 Algorithme de Johnson
20 Manipulation de dates

30 Gestion d'un lexique


31 Allocation dynamique
32 Gnrateur pseudo-alatoire

Sujets de travaux pratiques

Faire une preuve de programme


Manipuler les chanes de caractres
Approfondir la cration de bibliothque
Manipuler des pointeurs
Notions sur les permutations
Approfondir les tableaux
Approfondir les pointeurs
Dfinir des types personnaliss
Manipuler les numrations
Dfinir des structures
Approfondir les numrations
Approfondir les matrices
Approfondir les numrations

Approfondir les structures

Approfondir le floutage
Manipuler des tableaux de pointeurs
Approfondir les chanes
Allocation dynamique
Gestion de la mmoire
Approfondir allocation dynamique
Mthodes pseudo-alatoires

Supports de cours vol.2 Priode 2005-2014

N Nom

Prrequis principaux

Objectifs

33 Nombres hexadcimaux
34 Rpertoire tlphonique

Manipuler des chanes


Allocation dynamique
Allocation dynamique
Dfinir des structures

35 Fichiers & arguments de programme

Syntaxe de la fonction main

36 Diaporama

39 Fonctions rcursives

Allocation dynamique
Manipuler des fichiers
Allocation dynamique
Manipuler des fichiers
Manipuler des fichiers
Allocation dynamique
crire des fonctions
Notion de rcursivit

Approfondir allocation dynamique


Approfondir chanes de caractres
Approfondir indirections multiples
Approfondir tableaux de pointeurs
Lecture/criture dans un fichier
Arguments en ligne de commande
Approfondir les fichiers
Utiliser la triple indirection

40 Approximations numriques

Fonctions rcursives

41 Figures fractales

Fonctions rcursives

Approfondir la rcursivit
Approximation numrique
Approfondissement de la rcursivit
Notion de fractale

42 Listes chanes

Notion de liste
crire une fonction

Manipuler des listes

43 Disques & guirlandes

Manipuler des listes

44 Listes de caractres

57 Tri cocktail

Manipuler des fichiers


Manipuler des listes
Fonctions rcursives
Manipuler des listes
Fonctions rcursives
Manipuler des listes
Manipuler de listes
Manipuler des structures
Enveloppe d'un nuage de points
Manipuler des listes
Manipuler des chanes de caractres
Notion de pile de donnes
Manipuler des piles de donnes
Analyse d'expressions
Manipuler des piles de donnes
Fonctions rcursives
Fonctions rcursives
Utiliser des numrations
Manipuler des piles de donnes
Fonctions rcursives
Manipuler des piles
Notion de file de donnes
Manipuler des numrations
Manipuler un labyrinthe
Manipuler des tableaux
Notion de tri
Manipuler des tableaux
Tri bulle

Approfondir les listes


Approfondir les types structurs
Approfondir les listes
Approfondir les fichiers
Approfondir la rcusivit
Approfondir les listes
Approfondir la rcursivit
Tracer des graphiques
Manipuler des listes doubles
Approfondir les types structurs

58 Reprsentation des tris

Trier un tableau

59 Tris sur listes

63 Plus longue sous squence commune

Manipuler des listes


Trier un tableau
Manipuler des listes
Fonctions rcursives
Manipuler des listes
Fonctions rcursives
Manipuler des listes
Manipuler des chanes de caractres
Fonctions rcursives
Calcul de complexit

64 Arbres binaires

Fonctions rcursives

37 Stock d'une librairie


38 Automates cellulaires

45 Tapis de Sierpiski
46 Suite de Syracuse
47 Enveloppe d'un nuage de points
48 Marches de Graham et Jarvis
49 Analyse d'expressions
50 Conversion d'expressions
51 Dtection de palindromes
52 Tours de Hano
53 Remplissage de formes
54 Parcours d'un labyrinthe
55 Gnration d'un labyrinthe
56 Tri par dnombrement

60 Reprsentation de l'ADN
61 Nombres de grande taille
62 Table de symboles

Approfondissement gnral
Approfondir les fichiers
Approfondir l'allocation dynamique
Fonctions rcursives

Approfondir les listes


Manipuler les piles de donnes
Approfondir les piles de donnes
Approfondir la rcursivit
Approfondir les piles de donnes
Approfondir l'allocation dynamique
Approfondir rcursivit
Calculer des complexits
Approfondir les piles de donnes
Manipuler les files de donnes
Approfondir piles de donnes
Approfondissement gnral
Trier un tableau
Approfondir le calcul de complexit
Approfondir le tri de tableau
Approfondir le calcul de complexit
Approfondir les tris
Approfondir la SDL
Trier une liste
Manipuler des listes
Approfondir les listes
Approfondir le calcul de complexit
Approfondir la rcursivit
Approfondir le calcul de complexit
Introduction au hachage
Programmation dynamique
Approfondir le calcul de complexit
Arbres binaires
Arbre binaires de recherche

Liste des prrequis et objectifs de chaque TP

Sujets de travaux pratiques

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 01

entres-sorties

Prsentation
Le but de ce TP est dapprendre :
Comment crire un programme simple, comportant seulement une fonction
principale ;
Comment afficher du texte lcran et saisir du texte entr par lutilisateur.

1 Organisation du code source


Les programmes en langage C sont structurs au moyen de fonctions. Cependant, celles-ci
seront tudies plus tard, et on ne les utilisera donc pas dans les premiers TP. Pour cette
raison, le code source de ces premiers TP aura une organisation particulire, de la forme
suivante :
int main()
{ // exercice 1
...
// code source de lexercice 1 ...
// exercice 2
...
// code source de lexercice 2 ...
...

// reste des exercices

return EXIT_SUCCESS;
}

Autrement dit, la fonction main contiendra tous les exercices, identifis par des
commentaires appropris. Quand un exercice sera termin, le code source correspondant sera
lui-mme plac en commentaire, afin de ne pas interfrer avec lexercice suivant.

2 Notion dentres-sorties
Le terme dentres/sorties dsigne les mcanismes utiliss pour quun programme puisse
recevoir/envoyer des donnes depuis/vers un flux. Un flux peut tre un fichier, un
priphrique (cran, clavier, etc), ou dautres entits. Dans ce TP, nous nous intressons
seulement lentre standard, qui est le clavier, et la sortie standard, qui est lcran. En
langage C, le flux dentre standard est appele stdin (pour standard input) et le flux de
sortie standard est appele stdout (pour standard output).
Il existe de nombreuses mthodes permettant deffectuer des entres/sorties en langage C,
suivant le type des donnes traiter. On distinguera les fonctions qui manipulent les donnes
de manire non-formate, c'est--dire caractre par caractre, et celles qui travaillent de
manire formate.
Par dfaut, laccs au flux est buffris, ce qui signifie quune zone de mmoire sert de
tampon. Par exemple, dans le cas du flux dentre standard, les donnes issues du clavier sont
stockes dans le tampon, et attendent que le programme ait besoin delles.

TP 01

Algorithmique et programmation

1/5

entres-sorties

programme.c

tampon
1239

1238

1237

1236

1235

1234

Lintrt de laccs buffris est que, tant que le programme ne demande pas laccs au
tampon, il est possible de modifier les donnes qui y sont contenues.
Remarque : pour pouvoir utiliser les fonctions dentre-sortie prsentes dans ce TP,
vous devez inclure la bibliothque stdio.h dans votre programme.

3 Entres/sorties non-formates
La fonction int getc(FILE *stream) renvoie le code ASCII du caractre qui a t lu
dans le flux stream. Si on veut saisir un caractre au clavier, on crira :
char c;
c = getc(stdin);

Si une erreur se produit, la fonction renvoie -1. On ne tiendra pas compte de cette
possibilit lorsquon travaille sur le flux standard stdin, mais il est important de connatre
cette proprit, qui sera utile plus tard.
La fonction getchar fonctionne exactement pareil que getc, la diffrence quon na pas
prciser quon utilise le flux standard :
char c;
c = getchar();

Ces deux fonctions getc prennent un caractre dans le tampon et le suppriment du


tampon. Si le tampon est vide, le programme se bloque jusqu ce quun char soit plac dans
le tampon, c'est--dire : jusqu ce quune valeur soit saisie au clavier.
La fonction int putc(int c, FILE *stream) crit le caractre dont le code ASCII est
c dans le flux stream. Si on veut afficher un caractre lcran, par exemple le caractre A,
on crira donc :
char c = 'A';
putc(c, stdout);

Si une erreur se produit, la fonction renvoie -1, sinon elle renvoie le code ASCII du
caractre qui a t crit. L encore, on ne tiendra pas compte, ici, de la possibilit derreur. La
fonction putchar fonctionne exactement pareil que putc sans prciser le flux :
char c = 'A';
putchar(c);

Exercice 1
En utilisant getchar et putchar, crivez un programme qui saisit un caractre et qui
laffiche lcran.

Exercice 2
Mme question avec deux caractres : dabord le programme saisit les deux caractres,
puis il affiche les deux caractres.
Remarque : pour changer de ligne, vous pouvez afficher le caractre '\n'.

TP 01

Algorithmique et programmation

2/5

entres-sorties

4 Sorties formates
La fonction putchar ne permet dafficher que des caractres. La fonction printf, elle,
permet deffectuer une sortie formate, et dafficher des valeurs de nimporte quel type
simple :
printf(format,exp1,...,expn);

La fonction affiche les valeurs des expressions exp1,...,expn. Le paramtre format est
une chane de caractre de formatage indiquant comment les expressions doivent tre
affiches. Cette chaine de caractres peut contenir deux sortes dinformations :
du texte normal, qui sera affich tel quel
du texte spcifiant des formats daffichage
Par exemple, pour afficher le texte normal bienvenue dans le programme, on fera (dans
lexemple, la ligne fonce reprsente le rsultat lcran) :
printf("bienvenue dans le programme");
bienvenue dans le programme

Un format daffichage prend la forme dun pourcent % suivi dune expression prcisant le
format. Par exemple, le format %d signifie que lon veut afficher un entier relatif exprim en
base
(entier dcimal) :
printf("%d",1234);
1234

Il est possible davoir du texte normal et des formats dans la mme chane de formatage :
printf("affichage du nombre : %d",1234);
affichage du nombre : 1234

Lors de laffichage, chaque format prsent dans la chaine de formatage est utilis pour
afficher la valeur dune des expressions passes en paramtre. Le 1er format sert afficher la
1re expression, le 2me format afficher la 2me expression, etc. :
printf("affichage du nombre 1 : %d. affichage du nombre 2 : %d",12,34);
affichage du nombre 1 : 13. affichage du nombre 2 : 34

On manipule des expressions, on nest donc pas limit des constantes littrales, on
peut utiliser des variables et des oprateurs, par exemple :
int a=5;
printf("%d plus %d egale %d",10,a,10+a);
10 plus 5 egale 15

Remarque : le caractre % est un caractre spcial dans une chane de formatage,


puisquil permet de dfinir un format Si on veut afficher le caractre % lui-mme, il faut crire
%% dans la chaine de formatage, afin que la fonction printf sache quil ne sagit pas dun
format :
printf("resultat des ventes : %d %%",87);
resultat des ventes : 87 %

Les principaux codes de formatage sont :


code
rsultat affich
%d
nombre entier relatif dcimal
%u
nombre entier naturel dcimal
%o
nombre entier naturel octal
nombre entier naturel hexadcimal
%x et %X
%p
nombre entier reprsentant une adresse (pointeur)
%c
caractre
%f
nombre rel dcimal
nombre rel dcimal en notation scientifique
%e et %E
Remarque : par dfaut, un rel est affich avec 6 chiffres aprs la virgule.

TP 01

Algorithmique et programmation

3/5

entres-sorties

Il est possible de prciser, entre le % et la lettre du format, un modificateur de formatage


prcisant le type de la donne afficher :
donne
codes concerns
option
rsultat affich
int
aucune
d, i, o, x, X, u
h
(unsigned) short
entier
l

rel

f, e, E

aucune
l
L

long
float
double
long double

En plaant une valeur entire entre le % et la lettre du format, on peut prciser le nombre
de chiffres minimal afficher. Pour un rel, le point dcimal compte comme un chiffre. Si le
nombre afficher ne contient pas assez de chiffres, les chiffes manquants sont remplacs par
des caractres espace. Si on prfre remplir le vide avec des caractres 0, il suffit de faire
prcder la valeur minimale dun zro.
printf("entier:%4d reel:%9f",12,1.23456);
entier: 12 reel: 1.234560
printf("entier:%04d reel:%09f",12,1.23456);
entier:0012 reel:01.234560

On peut galement fixer la prcision, c'est--dire le nombre de chiffres aprs la virgule en


faisant suivre le nombre prcdent dun point et dune valeur entire. Si le nombre afficher
contient plus de chiffres, un arrondi est ralis. Sinon, le nombre est complt avec des zros :
printf("%.8f %.2f",1.23456,1.23456);
1.23456000 1.23

Exercice 3
Soient les variables relles (utilisez des double) suivantes : x1=1.2345,x2=123.45,
x3=0.000012345, x4=1e-10 et x5=-123.4568e15. Affichez leurs valeurs avec %f et avec %e.

Exercice 4
Soient les variables relles (float) suivantes : x1=12.34567, x2=1.234567, x3=1234567,
x4=123456.7, x5=0.1234567 et x6=1234.567. Utilisez printf pour obtenir laffichage
suivant :
12.35
1234567.00
0.12

1.23
123456.70
1234.57

Exercice 5
crivez un programme qui affiche la valeur
%d, %f et %e. Quobserve-t-on pour %d ?

de type float avec les formats

5 Entres formates
La fonction scanf permet de saisir des valeurs de manire formate. Le principe est le
mme que pour printf : on utilise une chane de formatage, et une suite de paramtres.
scanf(format,adr1,...,adrn);

La diffrence est quici, les paramtres sont des adresses. Ainsi, pour saisir un entier, on
fera :
int i;
scanf("%d",&i);

TP 01

Algorithmique et programmation

4/5

entres-sorties

Loprateur & permet de prciser quon passe en paramtre non pas la variable i, mais son
adresse. On peut saisir plusieurs valeurs la fois, lutilisateur devra les sparer par un retour
chariot, un espace ou bien une tabulation :
int i,j,k;
scanf("%d%d%d",&i,&j,&k);

Cela signifie que par dfaut, il nest pas possible de lire le caractre espace avec scanf.
On utilise avec scanf les mmes codes de formatages (d, u, o, x, X, c, f, e, E) et
modificateurs (h, l, L) que pour printf. On peut prciser la longueur maximale de la
donne lue, en insrant une valeur avant le code de formatage (ou le modificateur). Par
exemple, pour saisir un entier de 5 chiffres maximum :
int i;
scanf("%5d",&i);

Il est galement possible de prciser que les valeurs lues doivent tre spares par des
caractres particuliers. Par exemple, pour lire 3 valeurs spares par des points-virgules :
int i,j,k;
scanf("%d;%d;%d",&i,&j,&k);

Remarque : scanf utilise un accs buffris au clavier, et ne consomme pas le dernier


retour chariot. On a donc le mme problme que pour getchar.

Exercice 6
crivez un programme qui saisit un entier avec scanf et affiche le triple de cette valeur.

Exercice 7
crivez un programme qui saisit une heure au format suivant : heures:minutes:secondes.
Le programme doit afficher les valeurs saisies de la manire suivante (en respectant
lalignement) :
Entrez lheure (hh:mm:ss) : 1:2:34
1 heure(s)
2 minute(s)
34 seconde(s)

TP 01

Algorithmique et programmation

5/5

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 02

types simples

Prsentation
Le but de ce TP est de manipuler les types simples du langage C. Pour illustrer le cours,
qui portait sur leur reprsentation en mmoire, nous allons travailler sur la diffrence existant
entre la faon dont un nombre est cod et la faon dont il est saisi/affich.
Remarque : les justifications et rponses textuelles doivent tre indiques sous forme de
commentaires, juste aprs le programme concern. Cette remarque est valable pour tous les
TP venir.

1 Caractres
Exercice 1
crivez un programme qui saisit un caractre et qui affiche :
Son code ASCII
Le caractre suivant dans la table ASCII
exemple :
Entrez un caractere : e
Le code ASCII de 'e' est 101
Le caractere suivant dans la table ASCII est 'f'

Testez votre programme avec plusieurs caractres. Essayez notamment avec le caractre
''. Que se passe-t-il ? Pourquoi ? Corrigez lventuel problme.

Exercice 2
crivez un programme qui saisit un code ASCII et qui affiche le caractre correspondant.
exemple :
Entrez le code ASCII : 101
Le caractere correspondant au code ASCII 101 est 'e'

2 Entiers
Exercice 3
crivez un programme qui affiche les valeurs
et
. Ces deux valeurs
doivent tre affiches une premire fois en tant quentiers non-signs, puis une seconde fois
en tant quentiers signs. Que se passe-t-il, et pourquoi ?
crivez un programme qui affiche les constantes
et
. Ces deux valeurs
doivent tre affiches successivement :
Au format entier naturel hexadcimal (%x ou %X) ;
En tant quentiers non-signs (%u) ;
Puis en tant quentiers signs (%d).
la suite de votre programme, ajoutez un commentaire dans lequel vous devez :
Indiquer la suite de bits codant en mmoire les entiers
et
.
Interprter les rsultats, sachant que
.

TP 02

Algorithmique et programmation

1/2

types simples

Exercice 4
crivez un programme qui affiche la valeur en dcimal (%d), octal (%o) et hexadcimal
(%X). Mme question avec la valeur
. Que se passe-t-il, et pourquoi ?

Exercice 5
crivez un programme qui saisit deux valeurs de type short et affiche la somme de ces
deux valeurs. Testez votre programme avec diffrentes valeurs, puis calculez
(
). Quobservez-vous ? Pourquoi ?
et

3 Rels
Exercice 6
Calculez la reprsentation de la constante
de type float (i.e. 0.1f) dans la
mmoire de lordinateur.
crivez un programme qui affiche successivement cette constante avec les prcisions
suivantes :
Un seul chiffre aprs la virgule ;
Dix chiffres aprs la virgule.
Quobservez-vous ? Proposez une explication.

Exercice 7
Calculer la valeur des constantes (1e-9+1e9)-1e9 et 1e-9+(1e9-1e9) demandez
votre programme dafficher
dcimales et expliquez le rsultat obtenu.
Proposez une solution pour obtenir un rsultat exact.

TP 02

Algorithmique et programmation

2/2

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 03

variables & oprateurs

Prsentation
Le but de ce TP est de comprendre comment les variables sont places en mmoire, et de
manipuler les oprateurs de base du C.
Dans les exemples de ce TP, les ?? reprsentent en ralit des valeurs numriques. Cellesci ne sont pas indiques car le but des exercices est de les deviner avant dexcuter le
programme.

1 Variables & adresses


Exercice 1
crivez un programme qui dclare :
Trois variables globales a, b et c de type short ;
Trois variables locales la fonction main d, e et f de type short.
Dans la fonction main, affichez les adresses de ces six variables, en utilisant le format
pointeur %p dans printf, pour afficher une adresse.
exemple : le programme doit afficher des valeurs de la forme suivante (o les ??
correspondent des valeurs connues seulement lexcution) :
&a:0x?????? &b:0x?????? &c:0x??????
&d:0x?????? &e:0x?????? &f:0x??????

En vous aidant des adresses affiches par votre programme, faites un schma de
loccupation de la mmoire par ces variables. Quobservez-vous ?

Exercice 2
Ajoutez une fonction dans votre programme, appele fonction :
void fonction()
{ ...
}

Vous devez la complter en remplaant les ... par la dclaration de trois variables g, h, et
i de type short, et en affichant leurs adresses.
Dans la fonction main, aprs laffichage de d, e et f, effectuez un appel la fonction
prcdente en insrant linstruction suivante :
fonction();

Toujours dans la fonction main, aprs cet appel, crez trois variables locales g, h, et i de
type short, et affichez leurs adresses.
En utilisant les adresses affiches par le programme, compltez le schma de lexercice
prcdent. Quobservez-vous ?

2 Oprateurs & transtypage


Exercice 3
crivez un programme qui saisit un caractre. Si le caractre est une majuscule, il doit tre
transform en minuscule. Sinon, le caractre ne doit pas tre modifi. Enfin, le caractre

TP 03

Algorithmique et programmation

1/2

variables & oprateurs

obtenu doit tre affich. Vous ne devez pas utiliser de valeur entire littrale (i.e. aucun
nombre ne doit apparatre dans le programme).
exemple : si lutilisateur saisit le caractre V :
Entrez le caractere a traiter : V
Caractere apres le traitement : v

Remarque : on ne considre que les majuscules sans accent (), cdille (), trma (), etc.

Exercice 4
crivez un programme qui saisit deux entiers puis calcule et affiche le rsultat de la
division entire.
exemple :
Entrez le premier operande : 17
Entrez le second operande : 5
17 = 5*3 + 2

Exercice 5
crivez un programme qui saisit deux entiers puis calcule et affiche le rsultat de la
division relle.
exemple :
Entrez le premier operande : 10
Entrez le second operande : 4
10/4 = 2.250000

Exercice 6
crivez un programme qui :
Demande lutilisateur de saisir une valeur relle ;
Tronque cette valeur de manire obtenir au maximum deux chiffres aprs la
virgule ;
Affiche le rsultat de la troncature.
exemple :
Entrez le nombre reel : 1.234
Resultat de la troncature : 1.230000

Remarque : il ne sagit pas de simplement limiter le nombre de chiffres affichs, mais


bien de modifier la valeur de la variable. Vous devez utiliser le transtypage explicite.

Exercice 7
Analysez le code source suivant, et essayez de prvoir ce qui sera affich lcran. Puis,
recopiez-le dans votre programme, excutez-le et vrifiez vos prdictions.
int main()
{ int x=5,y=15;
float u=2.1,v=5.0;
printf("x==x : %d\n",x==x);
printf("x==y : %d\n",x==y);
printf("x==u : %d\n",x==u);
printf("x==v : %d\n",x==v);
printf("x>4 || x<3 : %d\n",x>4 || x<3);
printf("x>4 && x<3 : %d\n",x>4 && x<3);
if(x)
printf("(x) : vrai\n");
else
printf("(x) : faux\n");
printf("x=7 : %d\n",x=7);
printf("x : %d\n",x);
printf("x=(7!=8) : %d\n",x=(7!=8));
printf("x : %d\n",x);
printf("(float)x : %d\n",(float)x);
}

Que pouvez-vous dduire en ce qui concerne la valeur dune expression daffectation ?

TP 03

Algorithmique et programmation

2/2

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 04

instructions de contrle

Prsentation
Le but de ce TP est de manipuler les structures de contrle vues en cours, et en particulier
les boucles.

1 Utilisation de la bibliothque mathmatique


Vous aurez besoin dutiliser la fonction mathmatique math.h, qui contient certaines
fonctions ncessaires lors de quelques calculs. Comme pour les autres bibliothques, il est
ncessaire de mentionner explicitement son utilisation dans votre programme grce la
directive #include :
#include <math.h>

Sous Windows, cest suffisant. Sous Linux, il faut en plus paramtrer votre projet de la
faon suivante :
Dans Project Explorer ( gauche), faites un clic-droit sur votre projet et
slectionnez Properties.
Allez dans C/C++ Build puis Settings.
Dans longlet Tool Settings, allez dans MinGW C Linker puis Libraries.
droite, dans Libraries (-l), cliquez sur le bouton permettant dajouter une
bibliothque, et entrez simplement m, puis validez avec OK.
Cliquez sur OK pour fermer la fentre.

2 Test simple avec alternative


Exercice 1
crivez un programme qui demande lutilisateur de saisir trois entiers , et , puis qui
affiche le plus grand de ces trois entiers. Respectez exactement la forme de lexemple donn
ci-dessous.
exemple :
Entrez les valeurs de a, b et c (sous la forme a:b:c) : 8:12:-32
Le plus grand des entiers est 12.

Exercice 2
crivez un programme qui demande lutilisateur dentrer trois rels , et puis qui
affiche les solutions de lquation
en fonction des valeurs de , et .
Vous devez utiliser la fonction sqrt() dfinie dans la bibliothque math.h, qui calcule la
racine carre dun rel.
exemples :
Deux solutions :
Entrez les valeurs des coefficients a, b et c du trinome (a doit etre non-nul).
a = 2.1
b = 1.2
c = 0.1

TP 04

Algorithmique et programmation

1/4

instructions de contrle

L'equation 2.10x^2 +
x1 = -0.470142 et

1.20x + 0.10 = 0 admet deux solutions :


x2 = -0.101287.

Une seule solution :

Entrez les valeurs des coefficients a, b et c du trinome (a doit etre non-nul).


a = 4
b = 4
c = 1
L'equation 4.00x^2 + 4.00x + 1.00 = 0 admet exactement une solution :
x = -1.000000

Pas de solution :

Entrez les valeurs des coefficients a, b et c du trinome (a doit etre non-nul).


a = 0.1
b = -1.2
c = 5.2
L'equation 0.10x^2 + -1.20x + 5.20 = 0 n'admet pas de solution.

3 Boucles simples
Exercice 3
crivez un programme qui :
Saisit un entier ;
Renverse lentier ;
Affiche le rsultat.
exemple :
Entrez lentier a renverser : 1234
Resultat : 4321

Exercice 4
Donnez le tableau de situation pour la valeur utilise dans lexemple prcdent.

4 Boucles imbriques
Exercice 5
crivez un programme qui affiche (en respectant lalignement indiqu dans lexemple cidessous) la somme des premiers entiers, pour allant de
.
exemple :
1 + 2 = 3
1 + 2 + 3 = 6
...
...
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = 55

Exercice 6
Faites une copie du programme prcdent, et modifiez-la de manire demander
lutilisateur de saisir la valeur de :
Si lutilisateur saisit une valeur strictement positive, le programme effectue la
mme tche qu lexercice prcdent, puis redemande une valeur lutilisateur
pour recommencer le traitement.
Si lutilisateur saisit une valeur ngative ou nulle, le programme sarrte.
exemple :
Entrez n ou
1 + 2 = 3
Entrez n ou
1 + 2 = 3
1 + 2 + 3 =
1 + 2 + 3 +
Entrez n ou

TP 04

une valeur<=0 pour terminer : 2


une valeur<=0 pour terminer : 4
6
4 = 10
une valeur<=0 pour terminer : -1

Algorithmique et programmation

2/4

instructions de contrle

Le programme se termine.

5 Suite de Fibonacci
On considre la suite de Fibonacci (

),

dfinie par :

Exercice 7
En utilisant une boucle, crivez un programme qui calcule itrativement le me terme de
la suite de Fibonacci. La valeur doit tre demande lutilisateur. chaque itration, le
programme doit afficher .
exemple :
Entrez la valeur de n : 16
u0=0
u1=1
u2=1
u3=2
u4=3
u5=5
u6=8
u7=13
u8=21

Exercice 8

On peut montrer que la suite (

u9=34
u10=55
u11=89
u12=144
u13=233
u14=377
u15=610
u16=987

),

vrifie

, o

est le nombre dor. Ainsi,

. Faites une copie de votre programme et modifiez-la pour tester cette


proprit (utilisez le type double). chaque itration, le programme doit afficher
rapport
.
Remarque :
exemple :

Entrez la valeur de n : 20
u0=0
u1=1
u2=1
u2/u1=1.000000000000000
u3=2
u3/u2=2.000000000000000
u4=3
u4/u3=1.500000000000000
u5=5
u5/u4=1.666666666666667
u6=8
u6/u5=1.600000000000000
u7=13
u7/u6=1.625000000000000
u8=21
u8/u7=1.615384615384615
u9=34
u9/u8=1.619047619047619
u10=55
u10/u9=1.617647058823529

et le

.
u11=89
u11/u10=1.618181818181818
u12=144
u12/u11=1.617977528089888
u13=233
u13/u12=1.618055555555556
u14=377
u14/u13=1.618025751072961
u15=610
u15/u14=1.618037135278515
u16=987
u16/u15=1.618032786885246
u17=1597
u17/u16=1.618034447821682
u18=2584
u18/u17=1.618033813400125
u19=4181
u19/u18=1.618034055727554
u20=6765
u20/u19=1.618033963166706

Exercice 9
Faites une copie de votre programme et modifiez-la pour dterminer quel est le rang
partir duquel est estim avec une prcision de
. chaque itration, le programme doit
afficher ,
et lerreur commise.

TP 04

Algorithmique et programmation

3/4

instructions de contrle

exemple :
u0=0
u1=1
u2=1
u2/u1=1.000000000000000
erreur : -0.618033988740000
u3=2
u3/u2=2.000000000000000
erreur : 0.381966011260000
u4=3
u4/u3=1.500000000000000
erreur : -0.118033988740000
u5=5
u5/u4=1.666666666666667
erreur : 0.048632677926667
u6=8
u6/u5=1.600000000000000
erreur : -0.018033988740000

u7=13
u7/u6=1.625000000000000
erreur : 0.006966011260000
u8=21
u8/u7=1.615384615384615
erreur : -0.002649373355385
u9=34
u9/u8=1.619047619047619
erreur : 0.001013630307619
u10=55
u10/u9=1.617647058823529
erreur : -0.000386929916470
u11=89
u11/u10=1.618181818181818
erreur : 0.000147829441818
...

Remarque : la fonction fabs, contenue dans la bibliothque mathmatique math.h,


permet dobtenir la valeur absolue dun rel.

6 Devinette
On veut programmer un jeu simple, dont les rgles sont les suivantes :
Dabord, le programme choisit un nombre entre et
au hasard ;
Puis, il demande lutilisateur de deviner cette valeur.
Si lutilisateur a bien devin, le jeu sarrte.
Sinon, le programme indique lutilisateur si la valeur propose est trop grande ou
trop petite. Puis, lutilisateur doit proposer une nouvelle valeur, et on recommence
ainsi jusqu ce que la valeur du programme soit trouve.
Le nombre de tentatives nest pas limit : le jeu sarrte quand lutilisateur a devin la
valeur choisie par le programme. Le score de lutilisateur correspond au nombre de tentatives.
Bien sr, le but du jeu est de trouver la valeur en un minimum de tentatives.

Exercice 10
crivez un programme qui implmente ce jeu.
exemple :
Jai tir un nombre au hasard : essayez de le deviner !
Premiere tentative ? 28
La valeur 28 est trop grande.
Tentative 2 ? 5
La valeur 5 est trop petite.
Tentative 3 ? 8
Oui, cest bien ca (8) ! Bravo, vous avez gagne !
Votre score est : 3

Remarque : pour tirer au hasard un entier entre et


, utilisez le code source suivant
(qui sera expliqu lors dun TP futur). Vous avez besoin dinclure la bibliothque time.h.
srand(time(NULL));
int n = 1 + rand()%100;

votre avis, quelle stratgie le joueur doit-il adopter pour obtenir le meilleur score (i.e. le
plus petit score) ?

TP 04

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut

TP 05

Universit
Galatasaray

crible dratosthne

Prsentation
Le but de ce TP est de manipuler les notions vues dans les cours et TP prcdents, en
particulier les tableaux, tests et boucles.

1 Dfinition
Un nombre entier
est premier ssi
et p nest divisible que par et par lui{
} lensemble des nombres premiers. De plus, pour tout
mme. On notera
, sera le me nombre premier, de sorte que
,
,
,
, etc.

2 Approche nave
Exercice 1
crivez un programme qui demande lutilisateur dentrer un nombre entier naturel, et
qui teste si ce nombre est premier. Si le nombre nest pas premier, le programme doit afficher
le plus petit diviseur. Le programme devra tester tous les diviseurs possibles en partant de .
exemple 1 :
Entrez le nombre naturel a tester : 17
17 est un nombre premier.

exemple 2 :
Entrez le nombre naturel a tester : 12
12 n'est pas un nombre premier : il est divisible par 2.

Rappel : loprateur permettant dobtenir le reste (modulo) de la division entire est %.

Exercice 2
Dans le main, faites une copie du code source de votre programme prcdent, et
modifiez-la de manire afficher tous les nombres premiers compris entre et la valeur
entre par lutilisateur (en incluant cette valeur).
Entrez un entier naturel (>2) : 9
1 est un nombre premier.
2 est un nombre premier.
3 est un nombre premier.
5 est un nombre premier.
7 est un nombre premier.

Exercice 3
Faites une copie de votre programme prcdent, et modifiez-la de manire stocker tous
les nombres premiers dans un tableau nomm premier, avant de les afficher. Llment i du
tableau doit contenir le me nombre premier : premier[0] contient , premier[1] contient ,
premier[2] contient , premier[3] contient , etc.

TP 05

Algorithmique et programmation

1/2

crible dratosthne

3 Crible dratosthne
Linconvnient de lalgorithme naf est quil effectue de
nombreuses divisions inutiles. Par exemple, il peut tester la
divisibilit par dun entier qui nest divisible ni par , ni par .
ratosthne tait un scientifique de lantiquit, qui a propos un
algorithme appel Crible dratosthne, qui permet dviter ces
calculs inutiles.

Exercice 4
Lalgorithme du Crible dratosthne pour dterminer les
nombres premiers compris entre et est le suivant :
On considre un tableau contenant tous les entiers de .
On supprime tous les multiples de (sauf ).
Parmi les nombres restants, on supprime tous les multiples de (sauf ).
On rpte ce traitement jusqu ce quil ny ait plus de nombre traiter.
Les nombres restants la fin du traitement sont les nombres premiers recherchs.
Appliquez manuellement cet algorithme pour trouver les nombres premiers compris entre
et .

Exercice 5
Il est peu pratique dimplmenter directement cet algorithme ici, en raison de la difficult
supprimer des lments dans un tableau. On se propose plutt dadapter notre programme de
faon exploiter le principe dratosthne :
Soit le tableau premier, utilis pour stocker les nombres premiers ;
On considre chaque entier de jusqu ;
Pour chaque entier , on teste sil est premier en le divisant par les nombres
premiers infrieurs (qui sont contenus dans le tableau premier) ;
Si est premier, on le rajoute dans le tableau. Sinon, on ne fait rien ;
On passe
.
Faites une copie du programme prcdent et modifiez-la pour y intgrer cette modification.

4 Amlioration
Exercice 6
Limplmentation de cet algorithme ncessite de dclarer un tableau de taille , ce qui
requiert une grande quantit de mmoire (si
est grand). Pourtant, on identifie forcment
moins de
nombres premiers, donc une partie de ce tableau est inutilise. Il est possible
dutiliser un tableau plus petit en utilisant la proprit suivante :
(
Prouvez la proprit

Exercice 7
Faites une copie de votre dernier programme, et modifiez-la de manire intgrer cette
amlioration permettant dutiliser un tableau de taille au lieu de .

TP 05

Algorithmique et programmation

2/2

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 06

chanes de caractres

Prsentation
Le but de ce TP est de manipuler les chanes de caractres : affichage, saisie,
modification, comparaison, etc.

1 Rappel
En langage C, une chane de caractres est un tableau de valeurs de types char, qui se
termine par le caractre de fin de chane, not '\0'.
Une chane de caractre peut tre affiche en utilisant la fonction printf et le code de
formatage %s :
char chaine[]="abcdef";
printf("la chaine est : %s",chaine);
La chaine est abcdef

De la mme faon, on peut saisir une chane de caractres grce la fonction scanf et au
code de formatage %s :
char chaine[10];
printf("Entrez la chaine : ");
scanf("%s",chaine);
Entrez la chaine : ghijkl

La saisie est termine par certains caractres spciaux comme '\n', mais galement par le
caractre despacement ' ', ce qui constitue un inconvnient si on veut saisir des chanes
contenant des espaces.
La fonction gets permet galement la saisie de chanes de caractres :
char chaine[10];
printf("Entrez la chaine : ");
gets(chaine);
Entrez la chaine : ghijkl

Au contraire de scanf, gets peut saisir les espaces. Par exemple, si lutilisateur saisit la
chane abcd efg hijk :
en utilisant scanf, le tableau chaine contiendra les valeurs suivantes :
{'a', 'b', 'c', 'd', '\0'}

en utilisant gets, le tableau chaine contiendra les valeurs suivantes :


{'a', 'b', 'c', 'd', ' ', 'e', 'f', 'g', ' ', 'h', 'i', 'j', 'k', '\0'}
Enfin, la fonction puts permet dafficher une chane de caractres :
char chaine[]="abcdef";
puts(chaine);
abcdef

TP 06

Algorithmique et programmation

1/3

chanes de caractres

2 Exercices
Exercice 1
crivez un programme qui :
1. Demande lutilisateur de saisir une chane de caractres.
2. Calcule la longueur de la chane, c'est--dire le nombre de caractres taps par
lutilisateur.
exemple :
Entrez une chaine de caracteres : abcd
Il y a 4 caracteres dans la chaine "abcd".

Remarque : vous devez obtenir exactement laffichage ci-dessus, notamment les


guillemets. Attention ne pas confondre la longueur de la chane et la taille du tableau qui la
contient.

Exercice 2
crivez un programme demande lutilisateur de saisir une chane de caractre
chaine1[5], puis qui recopie cette chaine dans un autre tableau chaine2[5].

exemple :
Entrez une chaine de caracteres : abc
La chaine 2 est : abc

La variable chaine2 pourrait-elle tre un tableau contenant moins de


de caractres ?

caractres ? Plus

Exercice 3
crivez un programme qui :
Demande lutilisateur de saisir deux chanes de caractres, qui sont stockes dans
les tableaux chaine1[5] et chaine2[5].
Concatne ces deux chanes pour obtenir une troisime chaine chaine3[9].
Affiche chaine3.
exemple :
Entrez la chaine 1 : abc
Entrez la chaine 2 : defg
La chaine 3 est leur concatenation : abcdefg

Pourquoi le tableau chaine3 na-t-il pas une taille de

caractres ?

Exercice 4
crivez un programme qui saisit puis compare deux chanes de caractres selon lordre
lexicographique de la table ASCII.
exemple 1 :
Entrez la chaine 1 : def
Entrez la chaine 2 : abc
Resultat : def > abc

exemple 2 :
Entrez la chaine 1 : abc
Entrez la chaine 2 : abcd
Resultat : abc < abcd

exemple 3 :
Entrez la chaine 1 : abc
Entrez la chaine 2 : abc
Resultat : abc = abc

Rappel : lordre lexicographique est une gnralisation de lordre alphabtique aux


caractres qui ne sont pas des lettres (chiffres, ponctuation, etc.).

Exercice 5
TP 06

Algorithmique et programmation

2/3

chanes de caractres

crivez un programme qui initialise une chaine de caractres chaine1, puis qui en fait
une copie inverse chaine2 et laffiche.
exemple :
La chaine 1 est abcd
La chaine 2 est son inversion : dcba

Attention : cette fois on ne demande pas lutilisateur de saisir la chane, elle est
directement dfinie dans le programme.

Exercice 6
crivez un programme qui fait la mme chose qu lexercice prcdent, mais cette fois
sans utiliser un deuxime tableau. Autrement dit, vous devez travailler directement dans
chaine1. Vous avez le droit une variable temp de type char.
Pour une chane de longueur , vous devez pour cela appliquer le principe suivant :
Intervertir le caractre et le caractre
;
Intervertir le caractre et le caractre
Intervertir le caractre et le caractre
Etc.

TP 06

Algorithmique et programmation

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 07

tableaux multidimensionnels

Prsentation
Le but de ce TP est de manipuler des tableaux multidimensionnels dentiers. On tudie
dabord leur stockage en mmoire, puis on effectue des calculs simples sur des tableaux
dimensions.

1 Occupation mmoire
Exercice 1
Soit un tableau short m[N][P][Q] pour
,
reprsentation graphique de son occupation de la mmoire.

et

. Dessinez la

Exercice 2
Donnez les formules permettant de calculer les adresses de m[i], m[i][j], et m[i][j][k]
en fonction de :
Adresse du tableau : m ;
Type des donnes quil contient : short ;
Index : i, j et k.
crivez un programme permettant de vrifier votre calcul : il demande lutilisateur de
saisir les valeurs i, j et k et affiche chaque adresse de deux faons diffrentes :
Adresses directement obtenues en appliquant loprateur dadressage & aux
expressions mentionnes au dbut de lexercice ;
Adresses calcules avec vos formules.
Bien sr, si vos formules sont correctes, vous devez obtenir les mmes adresses avec les
deux mthodes.
exemple : (les ?????? reprsentent des adresses connues seulement lexcution)
Entrez i,j,k (avec les virgules) : 1,2,0
Adresse du tableau m : 0x??????
Adresse relle de
m[1] : 0x??????
Adresse calcule de m[1] : 0x??????
Adresse relle de
m[1][2] : 0x??????
Adresse calcule de m[1][2] : 0x??????
Adresse relle de
m[1][2][0] : 0x??????
Adresse calcule de m[1][2][0] : 0x??????

Remarques :
N, P et Q doivent tre dclares comme des constantes.
La fonction sizeof(t) permet de dterminer combien doctets un type t occupe
en mmoire. Par exemple, sizeof(char) renvoie la valeur .

Exercice 3
crivez un programme qui initialise ce tableau de manire ce que llment situ
ladresse m+2x contienne la valeur x. Effectuez une vrification en utilisant vos formules de
lexercice prcdent, qui vous permettent de calculer 2x en fonction de i, j, et k.
exemple :
TP 07

Algorithmique et programmation

1/2

tableaux multidimensionnels

Entrez i,j,k (avec les virgules) : 1,2,0


Valeur theorique : xxxxx
Valeur effective : xxxxx

2 Oprations matricielles
Pour des raisons pratiques, on se concentre ici sur des matrices carres de dimension
.

Exercice 4
crivez un programme permettant dafficher une matrice int m[N][N] lcran, comme
ci-dessous.
exemple : affichage de la matrice identit
1
0
0
0

0
1
0
0

0
0
1
0

0
0
0
1

Remarque : on suppose la matrice contient uniquement des valeurs comprises entre

et

Exercice 5
crivez un programme qui place dans une matrice res[N][N] le rsultat de la
multiplication dune matrice m[N][N] par un scalaire int s. Vous devez initialiser m en
utilisant la mthode que vous voulez, puis calculer le produit et afficher son rsultat res.
Utilisez (en ladaptant) le code source de lexercice prcdent pour effectuer laffichage du
rsultat.

Exercice 6
crivez un programme qui calcule la transpose dune m[N][N] et place le rsultat dans
la matrice res[N][N]. Initialisez et affichez le rsultat comme dans lexercice prcdent.

Exercice 7
crivez un programme qui calcule la somme de deux matrices m1[N][N] et m2[N][N] et
place le rsultat dans la matrice res[N][N]. Initialisez et affichez le rsultat comme dans les
exercices prcdents.

Exercice 8
Mme chose avec le produit de deux matrices m1[N][N] et m2[N][N], dont le rsultat
est placer dans une troisime matrice res[N][N].

TP 07

Algorithmique et programmation

2/2

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 08

diagrammes en mode texte

Prsentation
Le but de ce TP est de dfinir et dutiliser des fonctions secondaires (par opposition la
fonction principale main). De nombreuses fonctions ont dj t utilises dans les TP
prcdents, en particulier pour laffichage et la saisie de texte. Dans ce TP, nous allons dfinir
nos propres fonctions.

1 Structure des programmes


partir de ce TP, les programmes seront structurs en utilisant des fonctions. Autrement
dit, on ne va plus mettre tout le code source dans la fonction main comme auparavant, mais
on va plutt utiliser plusieurs fonctions distinctes. Les noms des fonctions sont donns dans
les exercices.
Attention cependant, car chaque fois que vous crivez une nouvelle fonction, vous devez
la tester pour vous assurer quelle fonctionne. Pour cela, vous devez lappeler partir de la
fonction main, et ventuellement afficher les rsultats obtenus si ncessaire.
Un programme aura donc maintenant la forme suivante :
int ma_function1(int mon_parametre)
{ ... // traitement de la premire fonction
}
float ma_function2(int p1, float p2)
{ ... // traitement dune autre fonction
}
... // dfinition dautres fonctions
int main()
{ // exercice 1
... // test de la premire fonction
// exercice 2
... // test de la deuxime fonction
... // etc.
return EXIT_SUCCESS;
}

2 Carrs
Exercice 1
crivez une fonction void affiche_ligne(int n, char car) qui affiche n fois le
caractre car suivi du caractre espace ' ', et finit par un retour la ligne.
exemples :
Lappel affiche_ligne(3,'*') produira laffichage suivant :
* * *

TP 08

Lappel affiche_ligne(5,'+') produira laffichage suivant :


Algorithmique et programmation

1/3

diagrammes en mode texte

+ + + + +

Exercice 2
En utilisant la fonction affiche_ligne, crivez une fonction void affiche_carre(int
cote, char car) qui affiche un carr plein laide du caractre car, comme dans
lexemple ci-dessous.
exemple : lappel affiche_carre(5,'*') provoque laffichage suivant :
*
*
*
*
*

*
*
*
*
*

*
*
*
*
*

*
*
*
*
*

*
*
*
*
*

3 Triangles
Exercice 3
affiche_ligne,
crivez une fonction void
affiche_triangle(int cote, char car) qui affiche un triangle plein laide du caractre

En

utilisant

la

fonction

car comme dans lexemple ci-dessous.

exemple : lappel affiche_triangle(5,'*') provoque laffichage suivant :


*
*
*
*
*

*
* *
* * *
* * * *

Exercice 4
On voudrait maintenant afficher un triangle, mais en contrlant son orientation. crivez la
fonction affiche_triangle2, qui a le mme en-tte que affiche_triangle, avec en plus
un nouveau paramtre direction. Si ce paramtre vaut , lhypotnuse est tourne vers le
haut, comme dans lexemple prcdent. Si le paramtre vaut , elle est tourne vers le bas,
comme dans lexemple ci-dessous. Vous devez rutiliser la fonction affiche_triangle.
exemple : lappel affiche_triangle2(6,'*',1) provoque laffichage suivant :
*
*
*
*
*
*

*
*
*
*
*

* * * *
* * *
* *
*

Exercice 5
En utilisant uniquement la fonction affiche_triangle2, crivez la fonction void
affiche_grand_triangle(int cote, char car), qui affiche un triangle du mme type
que celui donn en exemple ci-dessous.
exemple : lappel affiche_grand_triangle(5,'*') provoque laffichage suivant :
*
*
*
*
*
*
*
*
*

TP 08

*
*
*
*
*
*
*

*
* *
* * *
* *
*

Algorithmique et programmation

2/3

diagrammes en mode texte

4 Croix
Exercice 6
En utilisant la fonction affiche_ligne, crivez une fonction void affiche_ligne2(int
n1, int n2, char car) qui affiche n1 fois
caractres espace, puis n2 fois le caractre
car suivi du caractre espace ' '.
exemples : (les caractres espace sont reprsents sous forme dunderscores ('_') pour
que les exemples soient bien comprhensibles)
Lappel affiche_ligne(3,4,'*') produira laffichage suivant :
______* * * *

Lappel affiche_ligne(8,2,'+') produira laffichage suivant :

________________+ +

Lappel affiche_ligne(0,3,':') produira laffichage suivant :

: : :

Exercice 7
En utilisant la fonction affiche_ligne2, crivez une fonction void affiche_croix(int
cote, char car) qui dessine une croix comme dans lexemple ci-dessous. Le paramtre
cote contrle la longueur des branches de la croix.
exemple : lappel affiche_croix(5,'*') provoque laffichage suivant :
*
*
*
*
* * * * * * * * *
*
*
*
*

Exercice 8
crivez une fonction affiche_croix2(int n, int largeur, char car) qui prend un
paramtre supplmentaire par rapport la fonction prcdente affiche_croix : le paramtre
largeur, qui contrle lpaisseur des branches de la croix.
exemple : lappel affiche_croix2(6,3,'*') provoque laffichage suivant :
*
*
*
*
* * * * *
* * * * *
* * * * *
*
*
*
*

*
*
*
*
*
*
*
*
*
*
*

*
*
*
*
* * * * *
* * * * *
* * * * *
*
*
*
*

Remarque : on suppose que le paramtre largeur prend une valeur impaire.

TP 08

Algorithmique et programmation

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 09

introduction la SDL

Prsentation
La SDL (Simple Direct Media Layer) est une bibliothque que
nous utiliserons pour programmer des applications graphiques. Il
sagit dun projet libre (LGPL) et multiplateforme Pour savoir
comment installer et utiliser la SDL avec Eclipse et la CDT,
veuillez consulter les annexes du cours sur kikencere.
Le but de ce TP est de se familiariser avec cette bibliothque,
son utilisation, et les notions relatives la reprsentation des informations graphiques, en
particulier les couleurs.

1 Cration dun projet


La SDL est une bibliothque possdant de nombreuses fonctionnalits, et cause de cela
elle est peut paraitre complique. Pour cette raison, vous ne lutiliserez pas directement : vous
passerez uniquement par des fonctions prdfinies spcialement pour chaque TP. Ces
fonctions sont runies dans une bibliothque appele graphisme.
Larchive fournie avec ce sujet contient cette bibliothque graphisme, ainsi quun
programme main.c. Notez que la librairie se compose de deux fichiers : le fichier den-tte
(header en anglais, do le .h) graphisme.h et le fichier de dfinition graphisme.c. Le
fichier den-tte contient :
Les directives dinclusion permettant dutiliser dautres bibliothques :
o #include <mabibliotheque.h> : bibliothques installes.
o #include "mabibliotheque.h" : bibliothques locales au projet.
Les dfinitions de constantes (macros) : #define FENETRE_LARGEUR 800
Les en-ttes (ou dclarations) de fonctions : void efface_fenetre(void);
Le fichier de dfinition contient :
Une directive dinclusion pour son fichier .h associ.
Limplmentation de chaque fonction, avec la description de son rle sous forme
de commentaire.

Exercice 1
Crez un nouveau projet, et copiez-y les fichiers contenus dans larchive fournie avec ce
sujet. Pour utiliser la bibliothque SDL, vous devez dabord modifier la configuration de votre
projet. Pour cela, suivez les instructions de lannexe concernant lutilisation de la SDL,
disponible sur kikencere.
Compilez et excutez votre projet : une fentre graphique vide (toute noire) devrait
safficher. Appuyez sur une touche du clavier pour fermer cette fentre et terminer le
programme.

TP 09

Algorithmique et programmation

1/4

introduction la SDL

2 Fentre graphique
Exercice 2
Dans la fonction main, la fonction initialise_fenetre provoque la cration et
louverture de la fentre graphique. La chane de caractre quelle prend en paramtre est le
titre de la fentre. crivez vos prnom et nom la place de ce titre.
Les dimensions de votre fentre graphique sont dfinies dans le fichier graphisme.h par
des constantes FENETRE_LARGEUR et FENETRE_HAUTEUR. Modifiez-les de manire obtenir
une fentre carre de dimensions
.
Remarque : il peut tre ncessaire de cliquer sur Project > Clean pour que les
modifications soient prises en compte lexcution.

3 Reprsentation en mmoire
La fentre graphique est enregistre en mmoire sous forme dune matrice appele
surface, dont chaque lment reprsente un pixel de la fentre. Un type spcifique appel
SDL_Surface est charg dimplmenter cette matrice.
Le nombre de bits allou au codage dun pixel (bits per pixel ou bpp) est dfini dans la
constante BPP de graphisme.h. La valeur utilise dans graphisme.h est de
bits pour
un codage en mode RVB (Rouge-Vert-Bleu), soit octets :
Un octet est allou pour reprsenter lintensit de chacune des composantes R, V
et B, soit 3 octets au total.
me
Le 4
et dernier octet est appel canal alpha. Il permet de grer la transparence
des images. La transparence est utilise pour crer une image compose en
superposant deux images.
La figure ci-dessous illustre ce principe de reprsentation, pour une fentre de
pixels.
= 55
= 5
=5
= 55
=
= 7
=
= 55
= 55
= 55
=
= 55

= 55
=5
=
= 55
= 55
= 5
=5
= 55
= 55
= 55
=
= 55

= 55
= 5
=5
= 55
= 55
= 55
=
= 55
=
= 7
=8
= 55

Surface

Fentre

Dans le cadre dun projet, on peut donc reprsenter une couleur de deux faons
diffrentes : une squence de entiers cods chacun sur octets, ou bien seul entier cod
sur octets. La SDL utilise deux types spcifiques pour cela : le type Uint8 (un octet,
comme son nom lindique) et le type Uint32 (4 octets). La bibliothque graphisme offre

TP 09

Algorithmique et programmation

2/4

introduction la SDL

deux fonctions permettant de passer dun format lautre : convertis_rvb (de Uint8 vers
Uint32) et convertis_couleur (de Uint32 vers Uint8).

Exercice 3
Dfinissez des constantes (macros) reprsentant les couleurs suivantes :
Bleu

Jaune

Rouge

Vert

Orange

Blanc

Gris

Noir

Nommez-les selon la forme suivante : C_COULEUR. Par exemple : C_BLEU, C_ORANGE,


etc. Pour dfinir leur valeur, utilisez la fonction convertis_rvb. Pour identifier les
composantes rouge-vert-bleu utiliser, vous pouvez soit procder par essais-erreurs, soit
consulter le web (ex : cette page Wikipedia).

4 Dessin dans la fentre


Il est important de remarquer que lorigine du repre servant dfinir les coordonnes des
pixels de la surface nest pas situe en bas gauche, comme cest la convention en
mathmatiques. Pour des raisons matrielles, elle est plutt fixe en haut gauche de lcran :

: pixel de coordonnes ,

Les modifications ralises sur une surface ne sont pas directement affiches lcran. Il
existe, comme pour les entres et sorties standards, un tampon (buffer) entre la surface et
lcran. Il faut provoquer le vidage du tampon pour obtenir la mise jour de laffichage. Ceci
est ralis grce la fonction rafraichis_fenetre.

Exercice 4
La bibliothque graphisme contient la fonction : void allume_pixel(int x, int
y, Uint32 coul) qui sert modifier la couleur dun pixel de la fentre. Ses paramtres
sont :
x : labscisse du pixel concern.
y : lordonne du pixel concern.
coul : la nouvelle couleur du pixel, sous forme dun entier de type Uint32.
Dans le fichier main.c, crivez une fonction trace_carre(int x, int y, int c,
Uint32 coul)qui dessine lcran un carr plein dont le sommet suprieur gauche a pour
coordonnes (x,y) et dont le ct a pour longueur c. Le paramtre coul correspond la
couleur utiliser pour dessiner et remplir le carr.

Exercice 5
Dans la fonction main, affichez un carr blanc au centre de votre cran. Le rsultat obtenu
devrait ressembler la capture dcran de gauche, ci-dessous :

TP 09

Algorithmique et programmation

3/4

introduction la SDL

Remarque : pensez rafraichir la fentre graphique !

Exercice 6
crivez une fonction trace_figure() qui dessine la figure suivante, compose de 7
carrs de couleurs diffrentes :
En haut droite, un carr rouge.
En bas gauche, un carr jaune.
Au centre, un carr blanc.
Au milieu gauche, un carr orange.
En bas droite, un carr vert.
Au milieu droite, un carr gris.
En haut gauche, un carr bleu.
Bien entendu, vous devez tester cette fonction en compltant la fonction main. Vous
devez obtenir quelque chose de similaire la capture dcran de droite, ci-dessus.

5 Animation de la fentre
La fonction void attends_delai(int delai) dfinie dans graphisme prend en
paramtre un entier delai reprsentant un temps exprim en ms. La fonction bloque
laffichage durant ce temps-l. Cette fonction permet danimer limage affiche lcran : il
suffit dafficher la surface, puis attendre un peu, puis afficher une modification, puis attendre
un peu, puis afficher une autre modification, attendre un peu, etc. Sans cette attente,
laffichage serait si rapide quun tre humain naurait pas le temps de voir les diffrentes
tapes de lanimation.

Exercice 7
Dfinissez une constante (macro) DELAI dont la valeur correspond au dlai dattente que
vous voulez utiliser dans votre animation. Lintrt de cette constante est quelle vous
permettra ensuite de contrler facilement la vitesse de lanimation. Le dlai recommand ici
est dune seconde (donc
ms).
Ensuite, crivez une fonction void anime_figure() qui effectue lanimation
suivante :
Affiche en haut droite de lcran un carr rouge ;
Dplace le carr au centre de lcran et il devient blanc ;
Dplace le carr en bas droite et il devient vert ;
Dplace le carr en haut gauche et il devient bleu ;
Dplace le carr en bas gauche et il devient jaune ;
Dplace le carr au milieu gauche et il devient orange ;
Dplace le carr au milieu droite et il devient gris ;
Replace le carr en haut droite et il redevient rouge.
Testez votre fonction anime_figure depuis la fonction main.

TP 09

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 10

modification des couleurs

Prsentation
Ce TP est bas sur lutilisation de la SDL, donc vous devez configurer votre projet de
manire pouvoir utiliser cette bibliothque, comme expliqu dans lannexe disponible sur
kikencere. Une archive contenant la bibliothque graphisme et un album de photos est
fournie avec ce sujet. Notez que graphisme a t complte avec de nouvelles fonctions,
dont vous aurez besoin dans ce TP. Le but du TP est de modifier les photos en appliquant
diffrents algorithmes de modification des couleurs.

1 Prparation
Exercice 1
Modifiez la fonction main afin dafficher gauche de lcran la photo nomme
image1.bmp contenue dans lalbum fourni avec ce sujet. Vous aurez besoin des fonctions
suivantes, inclues dans graphisme :
charge_image : cre une surface partir dun fichier bitmap, cest--dire une
image prsente en mmoire, mais encore affiche.
dessine_surface : recopie une surface dans la fentre graphique.
Vous devez obtenir le rsultat suivant :

2 Niveaux de gris
Une image en niveau de gris est compose de pixels dont lintensit lumineuse varie entre
le noir et le blanc. Un pixel dune image RVB est de couleur grise si toutes ses trois
composantes sont gales.
Pour transformer une image couleur en une image en niveaux de gris, on peut utiliser
lalgorithme suivant :
Pour chaque pixel de limage :
o On dtermine ses quantits de rouge, vert et bleu du pixel.

TP 10

Algorithmique et programmation

1/4

modification des couleurs

o On calcule la moyenne de ces trois valeurs, qui correspond au niveau de


gris du pixel.
o On calcule de nouvelles composantes RVB, chacune gale cette valeur.
o On applique ces nouvelles composantes au pixel situ dans la surface
rsultat.

Exercice 2
crivez une fonction SDL_Surface* convertis_gris(SDL_Surface* source)
qui reoit une image sous la forme de la surface source, et qui cre et renvoie une nouvelle
surface contenant la mme photo que source, mais en niveau de gris. Vous aurez besoin des
fonctions suivantes, inclues dans la bibliothque graphisme :
initialise_surface : cre une nouvelle surface vide.
composantes_pixel_surface : renvoie les composantes RVB pour un pixel
situ dans une image donne.
allume_pixel_surface : dessine un pixel dans une surface passe en
paramtre.
De plus, il est possible daccder aux dimensions dune surface au moyen de deux champs
w (width) et h (height) permettant dobtenir ses largeur et hauteur, exprimes en pixels.
Dans la fonction main, affichez droite de lcran la version en niveau de gris de la photo
image1.bmp. Vous devez obtenir le rsultat suivant :

Exercice 3
Enregistrez limage en niveau de gris, sous la forme dun fichier bitmap appel
image1.nivgris.bmp. Vous aurez pour cela besoin de la fonction sauve_surface
incluse dans graphisme.
Remarque : le chemin pris en paramtre par sauve_surface est relatif la racine du
projet. Pour crer une image appele image.bmp et situe dans le dossier album de votre
projet, vous devez donc utiliser le chemin "album/image.bmp".

Visualisez limage cre, en utilisant loutil par dfaut de votre systme dexploitation
(double-clic sur limage dans le Project Explorer dEclipse), afin de vrifier que limage
obtenue est bien correcte.
Remarque : Eclipse ne rafraichit pas automatiquement le Project Explorer. Aprs avoir
cr le fichier demand, vous devez donc slectionner le dossier album et demander son
rafraichissement manuellement (clic-droit puis Refresh, ou bien touche F5), pour voir
apparaitre le nouveau fichier.

TP 10

Algorithmique et programmation

2/4

modification des couleurs

3 Balance des couleurs


On sintresse maintenant des modifications permettant de changer lquilibre des
couleurs dans une photo. Il ne sagit donc plus de convertir une photo couleur en une photo en
niveaux de gris, mais plutt de modifier les couleurs de la photo.

Exercice 4
La modification de la balance des couleurs est ralise en augmentant ou en diminuant
chaque composante RVB. Cependant, les composantes tant codes sur un seul octet, il est
]. Pour cela, on va
ncessaire que le rsultat de la modification reste compris dans [
utiliser une fonction de seuil. Soit la valeur originale de la composante et la modification
quon veut lui apporter. Alors la fonction de seuil
est dfinie par :
(

crivez la fonction (informatique) seuil qui implmente la fonction (mathmatique) .


Rflchissez bien son en-tte. Depuis la fonction main, testez votre fonction seuil.
Remarque : si vous utilisez MS Window avec la SDL, la sortie standard sera redirige
vers un fichier stdout.txt gnr dans le rpertoire debug de votre projet. Cest donc l
quil faut regarder pour avoir les rsultats de vos tests.

Exercice 5
crivez la fonction den tte SDL_Surface* modifie_couleurs(SDL_Surface*
source, int delta_r, int
delta_v, int delta_b), qui reoit en paramtre la
photo originale source, et qui renvoie une nouvelle surface, reprsentant la photo dont les
couleurs ont t modifies. La modification est la suivante :
Pour chaque pixel de la photo originale :
o On dtermine ses quantits de rouge, vert et bleu du pixel.
o On calcule de nouvelles composantes en ajoutant respectivement
delta_r, delta_v, et delta_b aux composantes rouge, verte et bleue.
o On applique ces nouvelles composantes au pixel situ dans la surface
rsultat.
Remarque : vous devez, bien entendu, utiliser la fonction seuil pour effectuer le calcul
des nouvelles composantes.
Dans la fonction main, affichez droite de lcran la version modifie de la photo
image1.bmp. Par exemple, si on applique modifie_couleurs(source, 100, 0, 0),
on va ajouter
la composante rouge sans modifier les deux autres composantes. La photo
paratra donc plus rouge, comme illustr ci-dessous :

TP 10

Algorithmique et programmation

3/4

modification des couleurs

Quobservez-vous si vous utilisez les valeurs (


)?

) comme deltas ? Et pour

Exercice 6
Enregistrez

limage

modifie,

sous

la

forme

dun

fichier

bitmap

appel

image1.modif.bmp.

TP 10

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 11

passage de paramtres

Prsentation
Le but de ce TP est de manipuler et de mieux comprendre le fonctionnement des deux
mthodes de passage de paramtres vues en cours : le passage par valeur et le passage par
adresse.
Remarques :
Pour rpondre aux questions demandant une rponse textuelle (par opposition un
programme), donnez vos explications dans la fonction main, sous forme de
commentaires.
Dans les exemples de ce TP, les ?? reprsentent en ralit des valeurs numriques.
Celles-ci ne sont pas indiques car le but des exercices est de les deviner avant
dexcuter le programme.

1 Exprimentations
Exercice 1
crivez une fonction void test1(int x) qui reoit un entier x et affiche simplement
sa valeur et son adresse. Pour vrifier test1, effectuez les oprations suivantes dans la
fonction principale main :
1. Dclarez et initialisez une variable x ;
2. Affichez sa valeur et son adresse avec printf ;
3. Appelez la fonction test1 en lui passant x en paramtre ;
4. Affichez encore une fois la valeur et ladresse de x.
exemple :
@main : ladresse de x avant lappel
@main : la valeur de x avant lappel
@test1 : la valeur de x est ??
@test1 : ladresse de x est 0x??????
@main : la valeur de x apres lappel
@main : ladresse de x apres lappel

est 0x??????
est ??
est ??
est 0x??????

Remarque : pour afficher une adresse avec printf, on utilise le format %p (au lieu de
%d).
Avant dexcuter votre programme, tentez de deviner quelles valeurs vont tre affiches
la place des ?? de lexemple ci-dessus. Cette consigne est valable pour les autres exercices.
Comparez les adresses affiches pour x : comment expliquez-vous les diffrences
observes ?

Exercice 2
On garde exactement la mme fonction test1, mais cette fois on procde diffremment
dans la fonction main : au lieu de dclarer une variable x, on utilise une variable n.
exemple :
@main : ladresse de n avant lappel est 0x??????
@main : la valeur de n avant lappel est ??
@test1 : la valeur de x est ??

TP 11

Algorithmique et programmation

1/5

passage de paramtres

@test1 : ladresse de x est 0x??????


@main : la valeur de n apres lappel est ??
@main : ladresse de n apres lappel est 0x??????

Quobservez-vous ? Comparez avec laffichage obtenu lexercice prcdent, et donnez


une justification.

Exercice 3
crivez une fonction void test2(int x) qui reoit un entier x, affiche sa valeur et son
adresse, modifie x de manire la diviser par , puis affiche la nouvelle valeur de x. Dans la
fonction principale main, effectuez les oprations suivantes :
1. Dclarez et initialisez une variable n ;
2. Affichez sa valeur et son adresse ;
3. Appelez la fonction test2 en lui passant n en paramtre ;
4. Affichez encore une fois la valeur et ladresse de n.
exemple :
@main : la valeur de n avant lappel est ??
@main : ladresse de n avant lappel est 0x??????
@test2 : la valeur de x est ??
@test2 : ladresse de x est 0x??????
@test2 : la valeur de x apres la division est ??
@main : la valeur de n apres lappel est ??
@main : ladresse de n apres lappel est 0x??????

Exercice 4
crivez une fonction int test3(int x) qui reoit un entier x, affiche sa valeur et son
adresse, calcule x divis par , affiche le rsultat de ce calcul et renvoie ce rsultat par
valeur. Dans la fonction principale main, effectuez les oprations suivantes :
1. Dclarez et initialisez une variable n ;
2. Affichez sa valeur et son adresse ;
3. Appelez la fonction test3 en lui passant n en paramtre, et utilisez la valeur
renvoye par test3 pour mettre n jour ;
4. Affichez encore une fois la valeur et ladresse de n.
exemple :
@main : la valeur de n avant lappel est ??
@main : ladresse de n avant lappel est 0x??????
@test3 : la valeur de x est ??
@test3 : ladresse de x est 0x??????
@test3 : le resultat de la division est ??
@main : la valeur de n apres lappel est ??
@main : ladresse de n apres lappel est 0x??????

Exercice 5
crivez une fonction void test4(int x, int* resultat) qui reoit un paramtre
pass par valeur x et un paramtre pass par adresse resultat. Cette fonction doit effectuer
les oprations suivantes :
1. Afficher la valeur et ladresse de x ;
2. Afficher ladresse correspondant resultat ainsi que la valeur situe cette
adresse ;
3. Diviser x par et mettre le rsultat ladresse indique par resultat ;
4. Afficher de nouveau la valeur et ladresse de x ;
5. Afficher de nouveau ladresse correspondant resultat et la valeur situe
cette adresse.
Remarque : attention, le paramtre resultat est lui-mme une adresse, il ne sagit pas
dune variable classique.

TP 11

Algorithmique et programmation

2/5

passage de paramtres

Dans la fonction principale main, effectuez les oprations suivantes :


1. Dclarez et initialisez une variable n ;
2. Dclarez une variable r (il nest pas obligatoire de linitialiser) ;
3. Affichez les adresses et les valeurs de ces variables ;
4. Appelez la fonction test4 en lui passant n et ladresse de r en paramtres ;
5. Affichez encore une fois les valeurs et adresses de n et r.
exemple :
@main : la valeur de n avant lappel est ??
@main : ladresse de n avant lappel est 0x??????
@main : la valeur de r avant lappel est ??
@main : ladresse de r avant lappel est 0x??????
@test4 : la valeur de x est ??
@test4 : ladresse de x est 0x??????
@test4 : ladresse indiquee par le parametre resultat est 0x??????
@test4 : la valeur situee a cette adresse est ??
@test4 : la valeur de x apres la division est ??
@test4 : ladresse de x apres la division est 0x?
@test4 : ladresse indiquee par resultat apres la division est 0x??????
@test4 : la valeur situee a cette adresse apres la division est ??
@main : la valeur de n apres lappel est ??
@main : ladresse de n apres lappel est 0x??????
@main : la valeur de r apres lappel est ??
@main : ladresse de r apres lappel est 0x??????

Expliquez pourquoi il est inutile dinitialiser la variable r dans la fonction main.


Comparez ladresse de r dans la fonction main et celle indique par le paramtre
resultat dans la fonction test4 : quobservez-vous (justifiez) ?

Exercice 6
crivez une fonction void test5(int* x) qui reoit un paramtre pass par adresse x,
et effectue les oprations suivantes :
1. Afficher ladresse correspondant x ainsi que la valeur situe cette adresse ;
2. Modifier cette valeur en la divisant par ;
3. Afficher de nouveau ladresse correspondant x et la valeur situe cette adresse.
Dans la fonction principale main, effectuez les oprations suivantes :
1. Dclarez et initialisez une variable n ;
2. Affichez ladresse et la valeur de cette variable ;
3. Appelez la fonction test5 en lui passant ladresse de n en paramtre ;
4. Affichez encore une fois la valeur et ladresse de n.
exemple :
@main : la valeur de n avant lappel est ??
@main : ladresse de n avant lappel est 0x??????
@main : la valeur de r avant lappel est ??
@main : ladresse de r avant lappel est 0x??????
@test4 : la valeur de x est ??
@test4 : ladresse de x est 0x??????
@test4 : ladresse indiquee par le parametre resultat est 0x??????
@test4 : la valeur situee a cette adresse est ??
@test4 : la valeur de x apres la division est ??
@test4 : ladresse de x apres la division est 0x?
@test4 : ladresse indiquee par resultat apres la division est 0x??????
@test4 : la valeur situee a cette adresse apres la division est ??
@main : la valeur de n apres lappel est ??
@main : ladresse de n apres lappel est 0x??????
@main : la valeur de r apres lappel est ??
@main : ladresse de r apres lappel est 0x??????

Est-il ncessaire dinitialiser la variable n dans la fonction main ?

TP 11

Algorithmique et programmation

3/5

passage de paramtres

Comparez ladresse de n dans la fonction main et celle indique par le paramtre x dans
la fonction test5 : quobservez-vous (justifiez) ?

2 Fonctions mathmatiques
Exercice 7
crivez une fonction vabs qui calcule et retourne la valeur absolue dun rel x de type
float. La fonction doit recevoir x par valeur et renvoyer sont rsultat par valeur.
Noubliez pas de tester votre fonction partir de la fonction main. Cette remarque est
valide pour tous les exercices.

Exercice 8
crivez une fonction distance, qui prend en paramtres deux rels de type float x et y,
et calcule puis retourne leur distance. Cette fonction doit utiliser la fonction vabs prcdente.
Cette fois, on veut que le rsultat de la fonction soit pass par adresse, sous forme dun 3 me
paramtre res.

Exercice 9
On veut crire une fonction division_entiere qui calcule et renvoie la fois le quotient
q et le reste r de la division de deux entiers x et y. Doit-on utiliser un passage de paramtre
par valeur ou par adresse ? Pourquoi ? crivez et testez la fonction.

Exercice 10
On veut rsoudre une quation du 2me degr. Pour cela, on veut crire une fonction
calcule_racines qui calcule le discriminant du polynme et lutilise pour dterminer
lexistence de solution(s), puis pour les calculer si cest possible.
crivez une fonction qui reoit par valeur les trois coefficients a, b et c du polynme. La
fonction doit renvoyer deux sortes de rsultats :
Elle doit renvoyer par valeur un code indiquant sil existe une racine (code ),
deux racines (code ) ou pas de racine du tout (code ).
Si une ou plusieurs racines existent, elle doit la (ou les) renvoyer par adresse.
Donc, la fonction a besoin de deux paramtres supplmentaires r1 et r2, qui ne seront pas
obligatoirement utiliss (a dpend du discriminant). Tout laffichage doit tre effectu dans
la fonction de lexercice suivant, et non pas dans calcule_racine.
Remarque : La fonction calculant la racine carre dun rel x en langage C est sqrt(x).
Elle est contenue dans la librairie math.h, qui devra donc tre inclue dans votre programme.
Il est galement ncessaire de modifier un paramtre de compilation. Dans les proprits du
projet Eclipse, allez dans C/C++ Build puis Settings, puis Tool Settings, puis C Linker, puis
Libraries. droite, dans Libraries (-l), ajoutez une librairie simplement appele m (m comme
mathmatiques).

Exercice 11
crivez une fonction void affiche_racines(float a, float b, float c) qui
reoit les coefficients dun polynme du 2me degr, qui utilise calcule_racines pour
calculer ses racines et qui affiche le rsultat exactement comme indiqu ci-dessous.
exemple 1 : pour lappel affiche_racines(10, -4, 1) on obtient laffichage :
Traitement du polynome 10.00x^2 4.00x + 1.00 = 0
Il nexiste aucune racine relle pour ce polynome

exemple 2 : pour lappel affiche_racines(9, 12, 4) on obtient laffichage :


Traitement du polynome 9.00x^2 + 12.00x + 4.00 = 0

TP 11

Algorithmique et programmation

4/5

passage de paramtres

Il nexiste quune seule racine reelle pour ce polynome : r=-0.67

exemple 3 : pour lappel affiche_racines(3, -5, 2) on obtient laffichage :


Traitement du polynome 3.00x^2 + -5.00x + 2.00 = 0
Il existe deux racines reelles pour ce polynome : r1=0.67 et r2=1.00

TP 11

Algorithmique et programmation

5/5

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 12

algorithme de Bresenham

Prsentation
Dans ce TP, nous utiliserons la SDL, donc vous devez configurer votre projet de faon
approprie. Puis, copiez dans votre projet les fichiers de la librairie graphisme, contenus dans
larchive fournie avec ce sujet.

1 Rastrisation dune droite


On veut reprsenter un segment dans la fentre graphique en utilisant la fonction
allume_pixel de notre bibliothque graphique. Pour reprsenter un segment qui joint les
centres et de deux pixels, on allume, sur chaque colonne, le pixel dont le centre est le plus
proche du segment [ ]. Dans la figure ci-dessous, les carrs reprsentent les pixels de
lcran et les ronds les centres de ces pixels. Les pixels allums sont griss. Le segment [ ]
est donc reprsent par les 7 pixels griss.

Cette mthode n'est valable que pour un segment dont le coefficient directeur est compris
entre et . En effet, si le coefficient directeur est suprieur , il restera des lignes ne
contenant aucun pixel allum :

TP 12

Algorithmique et programmation

1/4

algorithme de Bresenham

On remdiera ce problme en parcourant les pixels en suivant les lignes plutt que les
colonnes.

2 Notations
) et (
) les coordonnes
Soient (
et
des extrmits du segment [ ]
dessiner. On note
et
.
) avec
Soient (
les coordonnes des pixels reprsentant le
segment [ ]. On a donc
,
et
,
.
On fait les hypothses suivantes :

et
: le point est situ en bas gauche du point (on raisonne
dans un repre classique).

: le coefficient directeur de la droite ( ) est compris entre et .


Lquation de la droite ( ) peut scrire :
(
dfinie par ( )

On lui associe lapplication affine

( )

)
(

3 Algorithme naf
On parcourt les pixels suivant les colonnes, donc
et pour tout k,
Pour tout k :
)
Si (
:
)me colonne le plus proche de la droite (
o Le pixel de la (
).
pixel de coordonnes (
o Donc on choisit :
.

TP 12

.
) est le

Sinon :
o Cest le pixel de coordonnes (
o Donc on choisit :
.

) qui est le plus proche.

Algorithmique et programmation

2/4

algorithme de Bresenham

Exercice 1
crivez une fonction trace_segment_naif(int xa, int ya, int xb, int yb) qui
trace, laide de la mthode dcrite ci-dessus, un segment joignant deux pixels et . Le
pixel doit tre situ gauche du pixel et le coefficient directeur de la droite ( ) doit tre
compris entre et .

4 Algorithme de Bresenham
Le principe de l'algorithme de Bresenham a le mme rsultat que celui expos au-dessus,
mais il n'effectue que des oprations daddition et de soustraction sur des entiers, amliorant
ainsi la vitesse d'excution.
)
Lvaluation de lingalit (
ncessite des calculs sur des nombres
rels. Afin de les viter, lalgorithme de Bresenham travaille plutt avec lentier
suivant :
)
)
2 ( (
En effet, le signe de
permet de dterminer le choix du pixel de coordonnes
(
) allumer, daprs lquivalence suivante (avec
):
( (
)
)
(
)
Donc :
o Si
:
o Si
:
Le calcul se fait par rcurrence, en utilisant la proprit daffinit de
(
On a les relations :
o
2 ( (
2 ( (
2
o
2 ( (
Si
:

)
)

2
Si

)
( ))
)

( (
2

2)

))
( (
2) (
)
2(
Daprs la relation de rcurrence ci-dessus, comme les valeurs de
et
sont entires,
les valeurs de
sobtiennent en effectuant uniquement des additions et des soustractions sur
des entiers.
2

Exercice 2
TP 12

Algorithmique et programmation

3/4

algorithme de Bresenham

crivez une fonction trace_segment_bresenham1(int xa, int ya, int xb, int
] en utilisant le principe dcrit ci-dessus. On suppose que le
yb) qui trace un segment [
point est situ gauche de , et que le coefficient directeur est compris entre et .

5 Gnralisation
Nous navons tudi que le cas o le point
se situe gauche du point
et o le
coefficient directeur est compris entre et . Mais il existe au total cas possibles rpertoris
dans larbre ci dessous :

est gauche

est dessous

parcours suivant
les colonnes

est droite

est gauche
est dessus

est droite

parcours suivant
les lignes

Le cas dtaill prcdemment est le 1er cas : est au-dessous et gauche de .


Pour le 2me cas ( est au-dessous et droite de ), on peut remarquer une symtrie
par rapport ( ) avec le 1er cas :
B

De mme, on peut retrouver les 3 et 4 cas par symtrie par rapport ( ).


Enfin, pour effectuer un parcours suivant les lignes (au lieu des colonnes), il suffit
dchanger dans les formule les
avec les
; ainsi que les
avec les .
me

me

Exercice 3
Copiez-collez votre fonction trace_segment_bresenham1 pour obtenir une fonction
] quelles que
trace_segment_bresenham2. Modifiez-la pour quelle trace le segment [
soient les positions des points et .

TP 12

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 13

histogramme des couleurs

1 Prsentation
Dans ce TP, on se propose de travailler sur la notion dhistogramme. Un histogramme est
un graphique permettant de reprsenter comment se rpartissent les valeurs dans un
chantillon donn.
Dans un premier temps, on dfinira des fonctions permettant de dfinir un histogramme
partir de donnes quelconques. Lun des objectifs du TP est de constituer une librairie
destine la gestion dhistogrammes. Dans un second temps, on appliquera ces fonctions
lanalyse dune image, afin den reprsenter la rpartition des couleurs.
Ce sujet est fourni avec les bibliothques alea et graphisme. La premire doit tre
complte pour permettre de gnrer des nombres alatoirement. La deuxime ne doit pas tre
modifie, et ne sera utilise que dans la dernire partie du TP. Une troisime bibliothque
histogramme devra tre cre pour afficher des histogrammes lcran.

2 Gnration de donnes de test


La premire chose faire avant de dfinir les fonctions permettant de crer des
histogrammes, et dobtenir des donnes pour tester ces fonctions. On sappuiera pour cela sur
la fonction int genere_entier(int limite), disponible dans la bibliothque alea, qui
renvoie un entier tir alatoirement et compris entre et la valeur limite.

Exercice 1
Crez un fichier main.c , puis une fonction main lintrieur de ce fichier. Incluez la
librairie alea. Dans la fonction main, utilisez la fonction genere_entier pour obtenir un
entier, et affichez-le lcran.

Exercice 2
Dans la bibliothque alea, crivez une fonction den tte void genere_tableau(int
tab[], int taille, int limite)qui initialise alatoirement le tableau tab, en
utilisant taille entiers gnrs alatoirement avec la fonction genere_entier.

Exercice 3
Sur le modle des bibliothques fournies avec ce sujet, crez et initialisez les deux fichiers
ncessaires la bibliothque histogramme (i.e. histogramme.h et histogramme.c)
Dans cette bibliothque, crez la constante (macro) VAL_MAX, qui doit prendre la valeur
.
Cette constante correspond la valeur maximale que nous manipulerons dans ce TP.
Toujours dans la bibliothque histogramme, crivez une fonction void
affiche_tableau(int tab[], int taille) capable dafficher le tableau tab pass
en paramtre, sous forme textuelle. Depuis la fonction main, testez vos fonctions en gnrant
alatoirement un tableau avec genere_tableau, puis en laffichant avec
affiche_tableau. Vous devez aussi inclure les bibliothques ncessaires.

TP 13

Algorithmique et programmation

1/4

histogramme des couleurs

exemple : pour le tableau {4,2,2,10,7,4,3,4,10,7,11,4,0,4,2,5,0,6,8,9,10}


vous devez obtenir exactement laffichage suivant :
tab[0]=4
tab[1]=2
tab[2]=2
tab[3]=10
tab[4]=7
tab[5]=4
tab[6]=3
tab[7]=4
tab[8]=10
tab[9]=7
tab[10]=11
tab[11]=4

tab[12]=0
tab[13]=4
tab[14]=2
tab[15]=5
tab[16]=0
tab[17]=6
tab[18]=8
tab[19]=9
tab[20]=10
...

3 Dfinition de lhistogramme
Exercice 4
Pour afficher lhistogramme, on a dabord besoin de compter le nombre doccurrences de
chaque valeur contenue dans le tableau : nombre de , nombre de , nombre de , etc. Dans
histogramme, crivez une fonction void decompte_valeurs(int tab[], int
taille, int decompte[]). La fonction reoit un tableau tab contenant taille entiers
compris entre et VAL_MAX. Elle doit complter le tableau decompte, dont la taille est
VAL_MAX+1, de manire ce que la valeur decompte[i] corresponde au nombre
doccurrences de la valeur i dans tab.
exemple : pour le tableau prcdent, on obtiendrait le dcompte {2,0,3,1,5,1,1,2,1,
apparait fois dans tab, la valeur napparait
jamais, la valeur apparait fois, etc.
1,3,1...}. En dautres termes : la valeur

Testez votre fonction dans la fonction main sur le tableau tab prcdemment cr, et
affichez (grce affiche_tableau) le tableau decompte que vous obtenez.
Remarque : on ne connait pas, a priori, les valeurs contenues dans le tableau decompte
reu par la fonction. Vous devez donc penser linitialiser.

Exercice 5
Dans
la
bibliothque
histogramme,
crivez
une
fonction
void
histogramme_horizontal(int decompte[], int taille_d) qui affiche lhistogramme
horizontal du tableau de dcompte de taille taille_d pass en paramtre. Testez votre
fonction depuis main.
exemple : pour le tableau de dcompte prcdent, on obtient laffichage :
**
***
*
*****
*
*
**
*
*
***
*
...

Exercice 6
Dans

la

bibliothque

histogramme_vertical(int

TP 13

histogramme,
decompte[], int

crivez
taille_d)

Algorithmique et programmation

une
fonction
void
qui affiche cette fois
2/4

histogramme des couleurs

lhistogramme vertical du tableau de dcompte pass en paramtre. Testez votre fonction


depuis main.
exemple : pour le tableau de dcompte prcdent, on obtient laffichage :

*
*

*
*
*
*
*
*
*
*
*
* * * * * * * * * *...

4 Regroupement des valeurs


Exercice 7
On peut remarquer quen raison du nombre de valeurs diffrentes (de

), les
histogrammes prcdents sont difficilement lisibles. Il est possible damliorer cet aspect
grce la notion de classe. Dans le contexte des histogrammes, une classe est un groupement
de plusieurs valeurs. Par exemple, au lieu de reprsenter le nombre de valeurs , , par
lignes (ou colonnes) dtoiles, on peut toutes les regrouper, et ainsi utiliser une seule ligne (ou
].
colonne) pour reprsenter les valeurs de la classe [
exemple : pour le dcompte prcdent, si on fait des classes de

valeurs, on a :

******
*********
******
...

Dans histogramme, crivez la fonction void regroupe_classes(int decompte[],


int nbr_classes, int classes[]) qui reoit en paramtre un tableau de dcompte de
taille VAL_MAX+1, et qui regroupe ses valeurs sur nbr_classes. Le tableau classes doit tre un
tableau de taille nbr_classes, utilis pour stocker les valeurs calcules.
Remarque : on suppose que nbr_classes est un diviseur de VAL_MAX+1.

Exemple : dans le cas de lexemple prcdent, on obtient pour classes le tableau


{6,9,6,...}.

Exercice 8
Puisque nous avons dans tab
valeurs possibles (allant de VAL_MAX), on se
],
propose de dcouper notre domaine en
classes, chacune contenant donc valeurs : [
[
], [
], etc.
Dans la fonction main, gnrez avec genere_tableau un tableau tab de taille
.
Calculez son dcompte avec decompte_valeurs, puis utilisez regroupe_classes pour
regrouper les valeurs obtenues sur
classes. Affichez lhistogramme pour ces classes, avec
histogramme_horizontal.

Exercice 9
La lisibilit a t amliore, mais dans le cas prcdent on voit que sil y a un grand
nombre de valeurs, le nombre important dtoiles mises sur la mme ligne (ou colonne)
empche de lire convenablement lhistogramme. On va donc regrouper les toiles : au lieu de
reprsenter une seule occurrence, une toile va maintenant en reprsenter plusieurs.
Dans histogramme, crivez une fonction void regroupe_etoiles(int
classes[], int nbr_classes, int etoiles[], int echelle), qui ralise ce
regroupement des toiles. Le tableau classes est celui obtenu avec regroupe_classes,
donc il sagit dun tableau de dcompte dont les valeurs ont t regroupes par classe, et sa

TP 13

Algorithmique et programmation

3/4

histogramme des couleurs

longueur est nbr_classes. Le tableau etoiles est complter par votre fonction, de
manire ce que chaque toile de etoiles corresponde echelle toiles dans classes.
exemple : dans le cas de lexemple prcdent, si on applique regroupe_etoiles avec
une chelle de , alors on obtient pour etoiles le tableau {2,3,2,...}.

5 Couleurs dune image


On veut maintenant utiliser nos fonctions pour analyser une image. Comme on la vu dans
les TP prcdents, chaque pixel dune image est caractris par ses trois composantes RVB.
Nous allons reprsenter la distribution dune composante en particulier, sous forme
dhistogramme.

Exercice 10
Dans main.c, crivez une fonction void extrais_composantes(SDL_Surface
*surface, int tab_r[], int tab_v[], int tab_b[]) qui reoit une image sous
forme de surface, et qui complte les trois tableaux passs en paramtres. Le nombre
dlment de chaque tableau correspond au nombre de pixels dans limage. Chaque lment
du tableau reprsente la composante dun pixel de limage : rouge pour tab_r, vert pour
tab_v et bleu pour tab_b.

Exercice 11
Dans main.c, crivez une fonction void analyse_surface(SDL_Surface
*surface) qui reoit une image sous forme de surface, et qui affiche
histogrammes
verticaux, chacun correspondant la distribution dune composante. Pour cela, la fonction
doit :
1) Extraire
les
composantes
avec
extrais_composantes ;
2) Dcompter les valeurs avec decompte_valeurs ;
3) Regrouper les valeurs en
classes avec
regroupe_classes ;
4) Regrouper les toiles avec regroupe_etoiles, en
utilisant une chelle de
;
5) Afficher
les
trois
histogrammes
avec
histogramme_vertical.
Dans la fonction main, chargez une image sous forme de
surface, et appliquez analyse_surface pour tester votre
fonction. La figure ci-dessous donne une ide du rsultat obtenu
pour la composante rouge, avec limage image1.bmp.
L'histogramme pour le rouge est :
-----------------------------------------------------------------|
*
|
|
* *
|
|
* * *
|
|
* * * *
|
|
* * * *
|
|
* * * * * *
|
|
*
* * * * * *
|
|
*
* * *
* * * * * *
* * * * * * * *
|
------------------------------------------------------------------

Linterprtation de cet histogramme est que la photo comporte beaucoup de rouge : en


effet, la distribution montre un pic pour des valeurs leves de la composante R. Autrement
dit, il est frquent quun pixel possde une forte composante de rouge.

TP 13

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 14

proprits arithmtiques

Prsentation
Le but de ce TP est dapprofondir les tableaux et fonctions, en manipulant des notions
issues de larithmtique. Nous allons en particulier travailler avec les diviseurs dun nombre
entier, que nous reprsenterons sous forme de tableau. Pour en simplifier le traitement, nous
nous limiterons des entiers possdant N diviseurs (o N est une constante).

1 Diviseurs dun nombre


Exercice 1
Dfinissez la constante N sous forme de macro. crivez une fonction void
calcule_diviseurs(int n, int diviseurs[N], int *d) qui identifie tous les
diviseurs de lentier n (y compris n lui-mme) et les range dans le tableau diviseurs, dans
lordre croissant. La fonction renvoie par adresse le nombre de divisieurs identifis, grce au
paramtre d. On supposera que
. Testez votre fonction depuis la fonction main, en
affichant le tableau obtenu.
exemple : pour n=6, on obtient le tableau {1,2,3,6} et d=4.

Exercice 2

Pour tout entier naturel


, on note ( ) la somme des diviseurs propres de , i.e. la
somme de tous ses diviseurs sauf lui-mme.
exemples :
( )

;
( )

;
( )

;
( )

, pour tout nombre premier .


crivez une fonction int additionne_diviseurs_propres(int n) qui calcule la
somme des diviseurs propres de lentier n.

Exercice 3

On notera ( ) la somme des diviseurs de , i.e. la somme de tous ses diviseurs (y


compris lui-mme).
exemples :
( )

;
( )

;
( )

;
( )

, pour tout nombre premier .


crivez une fonction int additionne_diviseurs(int n) qui calcule la somme des
diviseurs de lentier n. Vous devez utiliser la fonction additionne_diviseurs_propres.

Exercice 4

TP 14

Algorithmique et programmation

1/3

proprits arithmtiques

crivez une fonction void affiche_sommes_diviseurs_propres(int max) qui


affiche :
Sur une premire ligne : la liste des entiers n compris entre et max ;
Sur la deuxime ligne : les valeurs de ( ) correspondantes.
On utilisera cette fonction avec un paramtre max infrieur ou gal , de sorte que les
nombres ( ) aient au plus chiffres. Attention : vous ferez en sorte que les nombres et
( ) soient aligns.
exemple : lappel affiche_diviseurs_propres(25) produit laffichage suivant :
n
: 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
s(n) : 01 01 03 01 06 01 07 04 08 01 16 01 10 09 15 01 21 01 22 11 14 01 36 06 16

2 Nombres parfaits, amicaux et sublimes


Exercice 5

( )
On appelle abondance dun nombre
la valeur ( )
.
exemples :
( )
Labondance de est : ( )
;
(
)
(
)
Labondance de
est :
;
( )
Labondance de
est : ( )
.
crivez une fonction int calcule_abondance(int n) qui calcule labondance du
nombre pass en paramtre. Vous devez utiliser additionne_diviseurs_propres.

Exercice 6

Un entier
est dit parfait sil est gal la somme de ses diviseurs propres ( ), i.e. :
( ). Autrement dit, un entier est parfait si son abondance est nulle, i.e. : ( )
.
exemples :

est parfait, car : ( )


;

nest pas parfait, car : ( )


;

est parfait, car : ( )


.
crivez une fonction int est_parfait(int n) qui renvoie si lentier n est parfait,
et sinon.

Exercice 7
Deux entiers
sont dits amicaux lorsque la somme des diviseurs propres de chacun
des deux est gal lautre nombre, cest--dire sils vrifient la fois ( )
et ( )
.
exemple : les nombres
et
sont amicaux, car on a :
(
)

(
)

crivez une fonction int sont_amicaux(int n, int p) qui retourne si les entiers
n et p sont amicaux, et sinon.

Exercice 8
Un entier
est dit sublime lorsque le nombre de ses diviseurs et la somme de ses
diviseurs sont tous les deux des nombres parfaits.
exemple :
est un nombre sublime, car ( )
, et on a donc
la fois :

diviseurs, et est un nombre parfait ;


( )

, et
est aussi un nombre parfait.
crivez une fonction int est_sublime(int n) qui dtermine si le nombre n est
sublime. La fonction renvoie si cest le cas, et sinon.

TP 14

Algorithmique et programmation

2/3

proprits arithmtiques

Remarque : on na identifi ce jour que deux nombres sublimes.

3 Nombres abondants et dficients


Exercice 9
On appelle nombre abondant un nombre
dont labondance est strictement positive :
( )
. Au contraire, on appelle nombre dficient un nombre dont labondance est
strictement ngative : ( )
.
exemples :

est un nombre dficient, car ( )


;

est un nombre abondant, car ( )


.
crivez les fonctions int est_abondant(int n) et int est_deficient(int n)
qui indiquent si le nombre n pass en paramtre est respectivement abondant ou dficient.
Chaque fonction doit renvoyer si cest le cas (nombre abondant ou dficient) et si ce nest
pas le cas.

Exercice 10
crivez une fonction void affiche_nombres(int max, int mode) qui reoit en
paramtres une valeur maximale max et un mode de fonctionnement mode. Ce mode a trois
valeurs possibles :
, et
. En fonction du mode, la fonction doit raliser lune des trois
tches suivantes :
Pour
: afficher tous les entiers dficients compris entre et max ;
Pour : afficher tous les entiers parfaits compris entre et max ;
Pour
: afficher tous les entiers abondants compris entre et max.
exemple : lappel affiche_nombres(100,1) affiche la liste des nombres abondants
infrieurs
:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.

TP 14

12
18
20
24
30
36
40
42
48
54
56
60
66
70
72
78
80
84
88
90
96

Algorithmique et programmation

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 15

algorithmes pour larithmtique

Prsentation
Le but de ce TP est de mettre en uvre la notion de preuve de programme vue en cours,
en lappliquant des fonctions simples relatives larithmtique.

1 Division euclidienne
On veut calculer, pour tous entiers positifs et avec
, le quotient et le reste de
la division Euclidienne de par . C'est--dire que lon veut obtenir les entiers et tels
que :
, avec
Voici la description dun algorithme qui effectue ce calcul :
Initialisation :
o
o
Itration : Tant que
,
o
o

Exercice 1
Appliquez cet algorithme aux entiers
lalgorithme.

et

, dcrivez toute les tapes de

Exercice 2
crivez une fonction division_euclidienne qui reoit en paramtres deux entiers
et , qui calcule le reste et le quotient de la division de par , et qui renvoie et . Cette
fonction utilisera lalgorithme dcrit ci-dessus.

Exercice 3
Quel est linvariant de boucle de cet algorithme ? Justifiez votre rponse.

2 Plus grand commun diviseur


On note pgcd
le plus grand diviseur commun de deux entiers
proprit suivante (qui correspond au thorme de Bachet-Bzout) :
Pour tous entiers positifs et , il existe deux entiers et tels que :
pgcd

et . On admet la

Soient et deux entiers, lalgorithme ci-dessous permet de calculer un couple


vrifie lquation
pgcd
:
Initialisation :
o
o
Itration : Tant que
,

TP 15

Algorithmique et programmation

qui

1/2

algorithmes pour larithmtique

o On note et le quotient et le reste de la division euclidienne de


o
o
Terminaison : on a
pgcd

par

Exercice 4
Appliquez cet algorithme au entiers

et

Exercice 5
crivez une fonction pgcd qui reoit en paramtre deux entiers et , qui calcule les
entiers , et tels que
pgcd
, et qui renvoie ces trois valeurs.

Exercice 6
Dmontrez que cet algorithme se termine.

Exercice 7
Dmontrez que la proprit suivante est un invariant de boucle de lalgorithme :

On pourra noter
aprs itrations.

{
pgcd
et

pgcd
les valeurs respectives de

et

Exercice 8
Dmontrez que la valeur obtenue pour le pgcd la fin de lalgorithme est correcte.

TP 15

Algorithmique et programmation

2/2

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 16

bibliothque chaines

Prsentation
Dans ce TP, on veut crire notre propre bibliothque chaine, qui regroupera des
fonctions permettant de manipuler des chanes de caractres. Une bibliothque est un
ensemble de fonctions proches, dans le sens o elles permettent gnralement de manipuler
les mmes donnes. Par exemple, stdio se charge des entres-sorties.
En langage C, une bibliothque xxxx se compose de deux fichiers : le fichier xxxx.h
contenant les en-ttes des fonctions, les types et les constantes ; et le fichier xxxx.c qui
contient le corps des fonctions.
Dans les TP o vous devrez dfinir une bibliothque, soyez bien attentif lemplacement
des fonctions, qui vous sera indiqu dans le sujet : soit dans le fichier main.c, soit dans la
bibliothque. Attention : dans ce dernier cas, cela signifie que les deux fichiers xxxx.c et
xxxx.h doivent tre mis jour. Si lemplacement nest pas prcis, alors il faut crire la
fonction dans main.c. Dans les deux cas, noubliez pas que chaque fonction crite doit tre
teste partir de la fonction main.

1 Prparation des fichiers


Exercice 1
Dans votre projet Eclipse, crez les fichiers suivants :
main.c : fichier principal qui contiendra la fonction principale main.
chaine.h : fichier den-tte (ou header) de la bibliothque.
chaine.c : fichier de corps de la bibliothque.

Exercice 2
Dans le fichier den-tte, copiez-collez le code source suivant, qui permet dempcher la
bibliothque dtre charge plusieurs fois lors de la compilation :
#ifndef CHAINE_H_
#define CHAINE_H_
// TODO a completer ici
#endif /* CHAINE_H_ */

Dans la suite, ce fichier devra contenir ;


Les inclusions des bibliothques utilises par les fonctions contenue dans notre
propre librairie, comme par exemple #include <stdio.h> ;
Les dclarations de constantes (#define ), et plus tard de types de donnes ;
Les en-ttes des fonctions contenues dans notre bibliothque.
Le code source correspondant ces 3 sortes dlments sera rajouter, dans lordre
indiqu, la place du commentaire "// TODO a completer ici" reprsent en rouge
dans le code source que vous avez copi-coll.

Exercice 3
Dans le fichier chaine.c, rajoutez la ligne suivante :

TP 16

Algorithmique et programmation

1/3

bibliothque chaines

#include "chaine.h"

Cette instruction indique que le fichier chaine.c est li au fichier chaine.h, et en


particulier quil utilise les bibliothques qui y sont incluses, et les constantes et types qui y
sont dclars.
Donc, faites la mme chose dans le fichier main.c : cela permettra votre fonction main
dutiliser les bibliothques, fonctions, types et constantes utilises ou dfinies dans la
bibliothque chaine.
Remarque : vous noterez qu la diffrence des utilisations prcdentes de #include,
comme par exemple quand on fait #include <stdio.h>, ici le nom de la bibliothque est
entour de guillemets ("xxx") et non pas de crochets (<xxx>) : cela est d au fait quil sagit
dune bibliothque dfinie localement (i.e. dont le code source se trouve dans le projet), et
non pas dune bibliothque standard localise au mme endroit que le compilateur.

2 Fonctions existantes
Les fichiers sont prts, et on veut maintenant commencer rajouter des fonctions notre
bibliothque. Dans le reste du sujet, pour chaque fonction demande, vous devez dabord
crire son en-tte dans chaine.h, puis la fonction complte (corps et en-tte) dans
chaine.c. De plus, vous devez tester chaque fonction partir de la fonction main, comme
dhabitude.
Remarque : dans chaine.h, chaque en-ttes doit tre suivie dun point-virgule ';'.
Comme expliqu au dbut du sujet, une bibliothque se compose de fonctions traitant
toutes du mme thme. Ici, il sagit de fonctions portant sur les chanes de caractres. Or,
nous avons dj fait un TP sur les chanes de caractres : nous allons donc commencer par
intgrer ce travail prcdent notre bibliothque. Les fonctions de cette section correspondent
des exercices de ce TP, veuillez consulter sa correction pour les obtenir, et le sujet lui-mme
si vous voulez plus de dtails sur le comportement des fonctions.
Remarque : attention aux en-ttes du prsent TP, qui sont lgrement diffrentes de
celles du TP pass.

Exercice 4
crivez une fonction int mesure_chaine(char* chaine) qui reoit une chane de
caractres chaine et calcule sa longueur, sans compter le caractre de fin de chane '\0'.

Exercice 5
crivez une fonction void copie_chaine(char* chaine1, char* chaine2) qui
recopie la chaine de chaine1 dans chaine2. On supposera que chaine2 correspond un
tableau dont la taille est suffisante pour y recopier chaine1.

Exercice 6
crivez une fonction int compare_chaines(char* chaine1, char* chaine2)
qui reoit deux chanes et les compare en utilisant lordre lexicographique de la table ASCII.
La fonction doit renvoyer
si la chaine1 est situe avant chaine2 dans lordre
lexicographique, si chaine1 et chaine2 sont exactement les mmes, et
si chaine1
est situ aprs chaine2 dans lordre lexicographique.

Exercice 7
crivez une fonction void inverse_chaine(char* chaine) qui inverse la chane
de caractre chaine passe en paramtre. Le traitement doit tre ralis sur place. Autrement
dit : vous devez travailler directement dans chaine.

TP 16

Algorithmique et programmation

2/3

bibliothque chaines

3 Nouvelles fonctions
Exercice 8
crivez une fonction void supprime_majuscules(char* chaine) qui prend en
argument une chaine de caractres chaine et qui supprime toutes les majuscules quelles
contient. Les caractres qui ne sont pas des lettres ne sont pas modifis. On suppose que la
chaine originale ne contient pas daccents.
exemple : pour chaine="afegAEfd CDghj!", aprs avoir appel la fonction, on obtient
la chaine "afegfd ghj!".
Remarque : votre fonction ne doit pas utiliser de tableau supplmentaire lors du
traitement. Autrement dit, aucun tampon (buffer) nest autoris, vous devez travailler
directement sur la chaine).

Exercice 9
crivez une fonction void remplace_majuscules(char* chaine) similaire
supprime_majuscules, avec la diffrence quau lieu de supprimer les majuscules, elle les
remplace par des minuscules.
exemple : pour chaine="afegAEfd CDghj!", aprs avoir appel la fonction, on obtient
la chaine "afegaefd cdghj!".

Exercice 10
crivez une fonction int compte_espaces(char *chaine) qui calcule le nombre
despaces ' ' contenus dans la chane de caractres passe en paramtre.
exemple : pour chaine="un deux trois", la fonction doit retourner .

Exercice 11
crivez une fonction int compte_mots(char *chaine) qui calcule le nombre de
mots contenus dans la chane de caractres chaine. On supposera que les mots peuvent tre
spars par un ou plusieurs espaces, et quil peut y avoir des espaces au dbut et la fin de la
chane.
exemples :
compte_mots("un deux trois") retournera la valeur ;
compte_mots("un
deux
trois") retournera aussi la valeur .
compte_mots(" un deux trois") retournera aussi la valeur .
compte_mots(" un deux trois
") retournera aussi la valeur .

Exercice 12
On dit quune chane de caractres chaine1 est un prfixe dune autre chane chaine2
ssi la chane chaine1 correspond exactement au dbut de la chane chaine2.
exemples :
"bon" est un prfixe de "bonjour".
"bonne" nest pas un prfixe de "bonjour".
"bonne" nest pas un prfixe de "bon".
"" (chane vide) est prfixe de nimporte quelle chane.
crivez une fonction int est_prefixe(char* chaine1, char* chaine2) qui
renvoie si chaine2 est un prfixe de chaine1, et sinon.

TP 16

Algorithmique et programmation

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 17

dcomposition dune permutation

Prsentation
Le but de ce TP est dabord de manipuler des concepts dj tudies : tableaux, pointeurs,
passage de paramtres, bibliothque ; mais aussi de faire un lien avec la notion de permutation
tudie en cours de mathmatiques.

1 Notion de permutation
} est une bijection
Soit un entier fix. Une permutation de lensemble {
} dans lui-mme. On peut reprsenter une permutation sur
de lensemble {
deux lignes sous la forme :
( ( ) ( ) ( )
)
(
)
Lensemble de ces permutations muni de la loi de composition des applications forme un
groupe (non commutatif si
)
lments.
Dans ce TP, on implmente une permutation sous forme dun tableau perm[] o pour
{
}, perm[i] est limage ( ) de par la permutation perm.
tout

Exercice 1
Les fonctions crites pour ce fichier ( lexception de la fonction main, bien entendu) vont
former une bibliothque appele permutation. Crez dabord un fichier permutation.c,
et crivez les fonctions suivantes dans ce fichier :
void saisis_permutation(int perm[N]) : demande lutilisateur de saisir
au clavier une permutation de longueur N.
void affiche_permutation(int perm[N]) : affiche la permutation passe
en paramtre, en utilisant la notation 2 lignes explique au dbut du sujet.
int verifie_permutation(int perm[N]) : vrifie que le tableau pass en
paramtre reprsente bien une permutation. Utilisez les proprits mathmatiques
dune permutation, expliques au dbut du sujet.

Exercice 2
Crez maintenant un fichier den-tte (header file) permutation.h, et copiez-y le code
source suivant :
#ifndef PERMUTATION_H_
#define PERMUTATION_H_
// a completer ici
#endif /*PERMUTATION_H_*/

Ce code source permet dempcher la bibliothque dtre charge plusieurs fois lors de la
compilation.
Compltez ce fichier permutation.h en crivant, la place du commentaire "// a
completer ici" :
1. La dfinition de la constante N ;
TP 17

Algorithmique et programmation

1/4

dcomposition dune permutation

2. Les en-ttes des

fonctions de lexercice prcdent.

Compltez le fichier permutation.c, en lui ajoutant la ligne suivante au tout dbut :


#include "permutation.h"

Cette ligne permet de relier permutation.c permutation.h, et rend possible


lutilisation de la constante N dans permutation.c (alors quelle est elle-mme dfinie dans
permutation.h).

Exercice 3
Crez un fichier main.c dans votre projet, et indiquez que vous y incluez permutation,
en utilisant #include exactement comme dans lexercice prcdent. Ainsi, le fichier main.c
pourra utiliser les fonctions dfinies dans la librairie permutation.
Dans le fichier main.c, testez vos fonctions en crivant un programme qui :
1. Demande lutilisateur de saisir au clavier une permutation.
2. Teste que les valeurs saisies dfinissent bien une permutation.
o Si les valeurs entres dfinissent une permutation, le programme affiche cette
permutation.
o Sinon, le programme indique lutilisateur quil sest tromp, et lui demande de
recommencer la saisie.
Le programme ne sarrte que quand lutilisateur saisit une permutation valide.
exemple : pour N=4
Saisissez limage de 0 : 4
Saisissez limage de 1 : 3
Saisissez limage de 2 : 2
Saisissez limage de 3 : 2
Saisissez limage de 4 : 0
Les valeurs saisies ne dfinissent pas une permutation.
Saisissez limage de 0 : 4
Saisissez limage de 1 : 3
Saisissez limage de 2 : 1
Saisissez limage de 3 : 2
Saisissez limage de 4 : 0
La permutation saisie est :
0 1 2 3 4
4 3 1 2 0

2 Composition et inversion
Exercice 4
Dans
la
bibliothque
permutation,
crivez
la
fonction
void
compose_permutation(int perm1[N], int perm2[N], int resultat[N]) qui
prend en argument deux permutations perm1 et perm2, calcule la composition de perm1 par
perm2, et place le rsultat dans le tableau resultat.
exemple : pour perm1={2,4,1,3,0} et perm2={1,4,3,2,0}, alors la composition
obtenue
est resultat={3,0,4,2,1}.

Exercice 5
permutation, crivez la fonction void
inverse_permutation(int perm[N], int resultat[N]), qui prend en argument
une permutation perm, qui calcule sa permutation rciproque, et qui la place dans le tableau
resultat. Utilisez pour cela la proprit suivante :

Toujours

dans

la

bibliothque

}
( ( ))
exemple : pour perm1={1,4,3,2,0}, on obtient resultat={4,0,3,2,1}.

TP 17

Algorithmique et programmation

2/4

dcomposition dune permutation

Exercice 6
Dans permutation, crivez la fonction int est_identite(int perm[N]) qui
renvoie si la permutation passe en paramtre est la permutation identit, et sinon.
exemples :
Pour perm={0,1,2,3,4}, la fonction renvoie ;
Pour perm={0,2,1,3,4}, la fonction renvoie .

Exercice 7
En utilisant la bibliothque permutation, compltez la fonction main de manire
effectuer les oprations suivantes :
Calculez la permutation rciproque de la permutation saisie par lutilisateur ;
Calculez la permutation obtenue en composant la permutation saisie avec sa
rciproque ;
Vrifiez que la permutation obtenue est bien lidentit.
exemple : (suite de lexemple de lexercice 3)
La permutation reciproque est :
0 1 2 3 4
4 2 3 1 0
La composee de loriginale par la reciproque est :
0 1 2 3 4
0 1 2 3 4
La compose est bien lidentite.

3 Notion de cycle
Une permutation est appele cycle de longueur (ou -cycle), sil existe des entiers
} tels que :
distincts dans {
( )

, ( )
,, (
)
, et (
)
;
Et :
{
} ()
Lensemble {
} sappelle le support du cycle . On utilise une notation
particulire pour les cycles, le cycle est ainsi not sous la forme :
(
).

Exercice 8
Dans permutation, crivez la fonction void affiche_cycle(int perm[]) qui
prend en argument une permutation cyclique de longueur inconnue et laffiche en utilisant la
notation propre aux cycles. Inutile de tester si la permutation passe en argument est bien un
cycle (on suppose que cest bien le cas).
exemple : pour cycle={0,4,2,7,3,5,6,1}, la fonction doit afficher :
( 1 4 3 7 )

4 Dcomposition en cycles
On veut vrifier le thorme suivant :
Toute permutation se dcompose en produit de cycles
supports disjoints.
en implmentant un algorithme qui effectue cette dcomposition (une preuve de la correction
de cet algorithme est une preuve en soi du thorme). On se propose dutiliser lalgorithme
suivant, dfini pour une permutation de lensemble {
}:
Si pour tout , ( )
, alors est lidentit, lalgorithme sarrte.
Sinon,
il
existe
tel
que
( )
et
on
affiche
le
(
( )
( )) o est le plus petit entier tel que ( )
.
TP 17

Algorithmique et programmation

3/4

dcomposition dune permutation

On rpte ce traitement en remplaant par


.
La permutation est gale au produit des cycles affichs par lalgorithme.

Exercice 9
Appliquer
(

manuellement
), (

cet

algorithme

aux

) et (

permutations

suivantes :

).

Exercice 10
Dans permutation, crivez une fonction void decompose_permutation(int
perm[N]) qui prend en argument une permutation, et qui affiche sa dcomposition en cycles
en utilisant lalgorithme dcrit ci-dessus. Pensez utiliser les fonctions des exercices
prcdents.
exemple : pour perm={2,4,0,7,3,5,6,1}, la fonction doit afficher :
( 0 2 )( 1 4 3 7 )

TP 17

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 18

nombres binaires

Prsentation
Dans ce TP, on veut effectuer diffrentes oprations sur des nombres binaires. Les
fonctions dfinies devront tre contenues dans une bibliothque spcifique que vous allez
dfinir, appele binaire. Chaque fonction doit tre teste depuis la fonction main, sans
utiliser aucun scanf ou fonction similaire. Autrement dit, lutilisateur ne doit avoir saisir de
valeurs. En particulier, les tableaux doivent tre initialiss lors de leur dclaration.

1 Reprsentation
On dcide de reprsenter un nombre binaire sous la forme dun tableau dentiers int de
longueur maximale
. Autrement dit, on manipulera dans ce TP des nombres dont
lexpression en base contient au plus
chiffres. Attention, cependant : pour faciliter le
traitement de ces nombres, les chiffres seront placs dans le tableau linverse de leur ordre
habituel.
)
exemple : le nombre entier (
sera reprsent par le tableau
{0,0,0,1,1,1,0,1}, de longueur .

Exercice 1
Crez le fichier main.c ainsi que les fichiers de la bibliothque binaire. Dans cette
bibliothque, dfinissez une constante N pour reprsenter la longueur maximale dun nombre
binaire.

Exercice 2
Dans binaire, crivez une fonction void affiche_binaire(int nombre[N],
int longueur) qui reoit en paramtre un tableau reprsentant un nombre binaire, et un
entier reprsentant le nombre de chiffres dans ce nombre binaire.
exemple : pour le tableau {0,1,1,1,1,1,1,0,1} (et donc la longueur ), qui
) , on doit obtenir exactement laffichage
correspond au nombre binaire (
suivant :
(1 0111 1110)_2

Exercice 3
Dans binaire, crivez une fonction int est_binaire(int nombre[N], int
longueur) qui dtermine si le nombre binaire pass en paramtre avec sa longueur est
valide. Puisquil est exprim en base , ce nombre doit contenir exclusivement les chiffres
et . La fonction renvoie si le nombre est valide, et sinon.
exemples :
) ).
Nombre {1,0,1,1,1,0} : la fonction renvoie (nombre binaire (
Nombre {1,8,1,1,1,0} : la fonction renvoie (pas un nombre binaire).

TP 18

Algorithmique et programmation

1/4

nombres binaires

2 Conversion dcimal-vers-binaire
Exercice 4
Dans binaire, crivez une fonction void divise_binaire(int x, int *q, int
*r) qui calcule la fois le quotient q et le reste r de la division entire de x par . Les deux
rsultats doivent tre passs par adresse.
exemple : pour x=7, la fonction doit renvoyer q=3 et r=1, puisque
.

Exercice 5
Lorsquon veut convertir un nombre exprim en base
en un nombre
exprim en
base , on utilise lalgorithme de la dcomposition binaire :
On effectue dabord la division entire de par .
o Le reste
de cette division correspond au dernier chiffre du nombre
binaire.
o Le quotient est utilis dans le reste du traitement.
On applique le mme principe , pour obtenir lavant-dernier chiffre du nombre.
On recommence ensuite avec le nouveau quotient pour obtenir lavant-avantdernier chiffre.
Ainsi de suite, jusqu obtenir itrativement le premier chiffre du nombre.
exemple : pour
:

On a alors le rsultat suivant :

) .

Dans binaire, crivez une fonction void decompose_binaire(int n, int


nombre[N], int *longueur) qui calcule la dcomposition binaire du nombre n en
utilisant lalgorithme dcrit ci-dessus. Le rsultat de cette dcomposition doit tre stock dans
le tableau nombre, et le nombre de chiffres obtenus doit tre renvoy par adresse au moyen
du paramtre longueur. Bien sr, le paramtre n est exprim en base .
exemple : pour n=13, on obtient le tableau {1,0,1,1} et la longueur , qui
) .
correspondent au nombre binaire (
Remarque : vous devez obligatoirement utiliser la fonction divise_binaire dans
decompose_binaire.

3 Conversion binaire-vers-dcimal
Pour un nombre binaire contenant chiffres, si on note son me chiffre, alors le nombre
correspondant son expression en base
correspond un polynme de degr :

exemple : pour le tableau {1,0,1,1} (et donc la longueur ), qui correspond au nombre
) , on a
binaire (
.
La mthode de Ruffini-Horner permet de calculer les polynmes efficacement. Elle est
base sur la factorisation du polynme, sous la forme suivante :
(
)

TP 18

Algorithmique et programmation

2/4

nombres binaires

((
)

(((((

Autrement dit, lalgorithme est le suivant :


On multiplie le chiffre de rang le plus lev (i.e. ) par 2, on additionne le chiffre
de rang infrieur (
);
On multiplie le rsultat de lopration prcdente par 2, on additionne le chiffre de
rang infrieur (
);
On recommence itrativement, jusquau chiffre de rang le plus bas (i.e. ).
exemple : pour {1,0,1,1}, on ralise les tapes suivantes :

Exercice 6
Dans binaire, crivez une fonction int recompose_binaire(int nombre[N],
int longueur) qui reoit un nombre binaire et sa longueur, qui le convertit en base
,
puis qui le renvoie par valeur. Vous devez appliquer la mthode de Ruffini-Horner.

4 Oprations
Exercice 7
Dans binaire, crivez une fonction void calcule_addition(int nombre1[N],
int longueur1, int nombre2[N], int longueur2, int nombre3[N], int*
longueur3) qui calcule la somme de nombre1 et nombre2, puis qui place le rsultat dans
nombre3. La longueur du rsultat est passe par adresse grce au paramtre longueur3.
)
exemple : pour les nombres nombre1={1,0,1} (cest--dire (
) et
nombre2={1,1} (cest--dire ( )
) on obtient les rsultats nombre3={0,0,0,1} et
)
longueur3=4, qui correspondent la valeur binaire (
.

Exercice 8
Dans binaire, crivez une fonction int compare_binaire(int nombre1[N],
int longueur1, int nombre2[N] , int longueur2) qui compare les deux nombres
binaires passs en paramtres, et renvoie :
Un entier positif si le 1er nombre est suprieur au 2nd ;
Zro si les deux nombres sont gaux ;
Un entier ngatif si le 1er est infrieur au 2nd.
exemples :
Pour {1,1,1} et {0,1} on obtient une valeur positive.
Pour {1,1,1} et {1,1,1} on obtient une valeur nulle.
Pour {1,0,1} et {1,1,1} on obtient une valeur ngative.

5 Exponentiation
Exercice 9
Dans binaire, crivez une fonction int calcule_puissance1(float x, int n,
float *res) qui calcule itrativement
. La fonction doit renvoyer cette valeur
par

TP 18

Algorithmique et programmation

3/4

nombres binaires

adresse, grce au paramtre res, et elle doit renvoyer par valeur le nombre ditrations
ncessaire au calcule de .
Remarque : quand vous testez votre fonction depuis la fonction main, affichez la fois
son rsultat et le nombre ditrations ncessaire au calcul.
exemple : pour x=2.5 et n=5, la fonction renvoie res=97.65625 et la valeur (i.e.
itrations).
2.500000^5=97.656250 (5 iterations)

Exercice 10
Soit un rel
, et un entier pour lequel on a la dcomposition binaire
Alors
peut scrire sous la forme suivante :
(
exemple : pour

, on a :
((

) )

Dduisez de cette proprit un algorithme pour calculer


laide de la dcomposition
binaire de
. Implmentez cet algorithme sous la forme dune fonction int
calcule_puissance2(float
x,
int
n,
float
*res). Comme
calcule_puissance1, la fonction calcule_puissance2 doit renvoyer par valeur le
nombre ditrations ncessaires au calcul de .
Remarque : votre fonction ne doit pas utiliser calcule_puissance1. Testez-la
galement en affichant la fois le rsultat et le nombre ditrations ncessaires son calcul.
exemples :
Pour x=2.5 et n=5, la fonction renvoie res=97.65625 et la valeur (i.e.
itrations).
2.5^5 = 97.65625 (2 iterations)

Pour x=2.5 et n=13, la fonction renvoie res=149011.609375 et la valeur


itrations).

(i.e.

2.500000^13=149011.609375 (3 iterations)

Exercice 11
et
quelconques, combien ditrations sont ncessaires
calcule_puissance1 pour calculer
? Et calcule_puissance2 ? Laquelle de ces
deux fonctions est la plus efficace, et pourquoi ?
Pour des valeurs

TP 18

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut

TP 19

Universit
Galatasaray

algorithme de Johnson

Prsentation
Le but de ce TP est de travailler les tableaux et les types numrs. Les en-ttes des
fonctions ne sont pas prcises (seulement leur noms) : cest volontaire, afin de vous faire
travailler cet aspect de la programmation. Vous devez dterminer vous-mme les types et
paramtres les plus appropris par rapport aux consignes.

1 Prsentation
Lalgorithme de Johnson (1963) permet de gnrer efficacement toutes les permutations
}.
de lensemble {

1.1 Cas
} en
Regroupons les permutations de {
observer que le nombre zigzague travers les blocs :
0
0
0
3

1
1
3
0

2
3
1
1

3
2
2
2

3
0
0
0

0
3
2
2

2
2
3
1

1
1
1
3

2
2
2
3

0
0
3
2

1
3
0
0

3
1
1
1

3
2
2
2

2
3
1
1

blocs de
1
1
3
0

0
0
0
3

1
1
1
3

2
2
3
1

permutations. On peut
0
3
2
2

3
0
0
0

3
1
1
1

1
3
0
0

0
0
3
3

2
2
2
3

On observe galement que si on retire le nombre , on obtient pour chaque bloc une des
}:
permutations de {
0 1 2

0 2 1

2 0 1

2 1 0

1 2 0

En reprenant le mme principe, on peut regrouper ces permutations en


permutations, dans lesquels le nombre zigzague, etc.

1 0 2

blocs de

1.2 Reprsentation des permutations


Pour gnrer les permutations en utilisant cette observation, Johnson reprsente une
permutation par des entiers munis dune girouette : on associe chaque entier une flche
indiquant une direction.
exemple :

Dfinitions :
Lorsque la girouette dun entier x est oriente vers un autre entier y, on dit que x
regarde y. Dans lexemple prcdent :
o
regarde
o
regarde
o
regarde
o
regarde
o
regarde
Lorsquun entier x est situ tout gauche (respectivement tout droite) et que sa
girouette indique la gauche (respectivement la droite), on dit que x regarde dehors.
Dans lexemple prcdent, et regardent dehors.
On dit quun entier est mobile sil ne regarde pas dehors et sil regarde un entier
plus petit que lui. Dans lexemple, seuls les entiers , , et sont mobiles.

TP 19

Algorithmique et programmation

1/3

algorithme de Johnson

1.3 Algorithme
} de la manire
Lalgorithme de Johnson gnre toute les permutations de {
suivante :

On commence avec la permutation


.
On rpte le traitement suivant :
On affiche la permutation courante.
On recherche le plus grand entier mobile (PGEM) m.
Si on trouve un entier mobile :
On change
et lentier que
regarde, sans changer le sens de
leurs girouettes respectives.
On inverse le sens des girouettes de tous les entiers
.
On recommence.
Si on ne trouve pas dentier mobile, lalgorithme se termine.

2 Implmentation
Exercice 1
En utilisant lalgorithme de Johnson, vrifiez la main que lon obtient bien les
}, comme dcrit prcdemment.
permutations de {

Exercice 2
Dfinissez un type numr t_girouette, permettant de dcrire lorientation dune
girouette. Dfinissez un type structure t_entier_girouette permettant de reprsenter un
entier et sa girouette.

Exercice 3
Une

permutation sera reprsente par un tableau de valeurs de type


t_entier_girouette. crivez une fonction initialise_permutation qui effectue
linitialisation (1er point de lalgorithme) de ce tableau, qui sera pass la fonction en
paramtre.
Remarque : notez que la taille de la permutation est ici variable ( la diffrence du TP
sur la dcomposition de permutations, o on utilise une constante ). Cette taille doit donc
tre passe en paramtre.
exemple : pour une taille
, la fonction doit renvoyer la permutation .

Exercice 4
crivez une fonction affiche_permutation qui affiche une permutation passe en
paramtre (3me point de lalgorithme).
exemple : pour la permutation
, on affichera :
<- <- <- -> <- -> ->
0 2 4 6 5 3 1

Exercice 5
crivez une fonction identifie_pgem qui calcule la valeur et la position du plus grand
entier mobile de la permutation passe en paramtre (4me point de lalgorithme).
exemple : pour la permutation
, la fonction doit renvoyer la position , qui
correspond .

Exercice 6

TP 19

Algorithmique et programmation

2/3

algorithme de Johnson

crivez une fonction deplace_entier qui reoit en paramtres (au moins) une
permutation et la position dun entier dans cette permutation. On suppose que la position
reue correspond un entier mobile. La fonction doit changer lentier situ cette position,
avec lentier quil regarde (6me point de lalgorithme).
exemples : pour la permutation
Si on spcifie la position , on obtient
.

Si on spcifie la position , on obtient


.

Exercice 7
crivez une fonction inverse_girouette qui inverse, dans une permutation, les
girouettes de tous les entiers strictement suprieurs un entier (7me point de lalgorithme).
La permutation et doivent tre passs en paramtres.
exemple : pour la permutation
et
, on obtient
.

Exercice 8
crivez une fonction johnson qui prend en paramtre un entier n et affiche toutes les
} en utilisant lalgorithme de Johnson.
permutations de {
exemple : pour
, on obtient laffichage suivant (similaire celui du dbut du sujet) :
<0
<0
<0
<3
->
3
<0
<0
<0
<-

TP 19

<1
<1
<3
<0
<0
->
3
<2
<2
<-

<2
<3
<1
<1
<2
<2
->
3
<1
<-

<3
<2
<2
<2
<1
<1
<1
->
3
<-

2
<2
<2
<3
->
3
->
2
->
2
->
2
<1

0
<0
<3
<2
->
2
->
3
<1
<1
->
2

1
<3
<0
<0
<1
<1
->
3
<0
<0

3
<1
<1
<1
<0
<0
<0
->
3
<3

Algorithmique et programmation

<1
<1
<3
->
3
<1
<1
<1

->
2
<3
<1
<1
->
3
<0
<0

<3
->
2
->
2
<0
<0
->
3
->
2

<0
<0
<0
->
2
->
2
->
2
->
3

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 20

manipulation de dates

Prsentation
Dans ce TP, on veut crer une bibliothque date
permettant de reprsenter et de manipuler des dates, en
dfinissant nos propres types structure et numr. Cette
bibliothque sera ensuite utilise dans dautres TP.

1 Reprsentation des mois


Exercice 1
Crez un projet et les fichiers ncessaires : date.c, date.h et main.c. Initialisez ces
fichiers de faon approprie (cf. les TP prcdents portant sur la dfinition de bibliothque).

Exercice 2
On veut reprsenter les mois avec un type numr (et non pas avec un entier). Ce type
doit contenir les symboles suivants : jan, fev, mars, avr, mai, juin, juil, aout, sept,
oct, nov et dec. De plus, on veut que chaque mois soit associ la valeur numrique
approprie : jan , fev , etc.
Dans date.h, dfinissez un type numr t_mois respectant ces contraintes.
Remarque : les types contenus dans une bibliothque xxxx doivent toujours tre dfinis
dans le fichier den-tte xxxx.h.

Exercice 3
Dans date, crivez la fonction void affiche_mois(t_mois m) qui affiche le texte
complet correspondant au mois pass en paramtre.
exemples :
affiche_mois(jan) doit afficher "janvier" ;
affiche_mois(fev) doit afficher "fevrier" ;
etc.
Contrainte : vous navez pas le droit dutiliser if dans cette fonction.

2 Reprsentation des dates


Exercice 4
Dans date.h, Dfinissez un type structure t_date permettant de reprsenter une date
dcompose en jour, mois et anne, comme par exemple : 20 novembre 2011. Le jour et
lanne sont des entiers naturels, alors que le mois est de type mois.

Exercice 5
Dans date, crivez une fonction affiche_date qui reoit une date en paramtre et qui
laffiche exactement comme indiqu ci-dessous.
exemple : pour la date prcdente, on obtient :

TP 20

Algorithmique et programmation

1/4

manipulation de dates

20 novembre 2011

Exercice 6
Dans date, crivez une fonction saisis_date qui permet lutilisateur de saisir une
date, et qui la renvoie par valeur.
exemple : saisie de la date donne dans lexemple prcdent
Entrez le jour : 20
Entrez le mois :
11
Entrez lanne : 2006

Remarque : noubliez pas que les valeurs des types numrs sont en ralit reprsentes
sous la forme dentiers.

Exercice 7
Dans date, crivez une fonction int compare_dates(t_date date1, t_date
date2) qui compare les deux dates passes en paramtres et renvoie un entier :
Ngatif si date1 est antrieure date2 ;
Zro si date1 et date2 sont exactement les mmes ;
Positif si date1 est postrieure date2.
exemples :
Pour les dates 01/01/2014 et 01/02/2014, la fonction renvoie
ngative) ;
Pour les dates 01/01/2014 et 01/01/2014, la fonction renvoie ;
Pour les dates 01/01/2014 et 01/02/2013, la fonction renvoie
positive).

(ou autre valeur

(ou autre valeur

Exercice 8
Dans date, crivez une fonction copie_date qui reoit en paramtre une date (i.e. une
valeur de type t_date) et cre une nouvelle valeur de type t_date qui est la copie de cette
date. vous de dcider si la copie doit tre passe par adresse ou par valeur.
Remarque : il sagit bien de crer une nouvelle valeur, et non pas de faire pointer deux
pointeurs diffrents sur la mme valeur en mmoire.

3 Calculs sur les annes


Exercice 9
Dans date, crivez une fonction int est_bissextile(int annee) qui prend une
anne en paramtre et renvoie si elle est bissextile, et sinon. Daprs Wikipedia, une
anne est bissextile ssi :
Soit elle est divisible par mais pas par
;
Soit elle est divisible par
.
exemples :
et
sont bissextiles,
et
ne sont pas bissextiles.

Exercice 10
Dans date, crivez une fonction int indique_jours(int annee, t_mois mois)
qui reoit en paramtre une anne et un mois, et renvoie le nombre de jours composant ce
mois lors de cette anne-l. Pensez utiliser la fonction prcdente.
Contrainte : vous ne pouvez utiliser quun seul if dans cette fonction.

Exercice 11

TP 20

Algorithmique et programmation

2/4

manipulation de dates

On veut amliorer la fonction saisis_date, de manire sassurer que les valeurs


reues sont bien valides. Dans date, crivez une fonction saisis_date_verif qui effectue
les tests suivants lors de la saisie de la date par lutilisateur :
Lanne doit tre un entier compris entre
et
(inclus) ;
Le mois doit tre un entier entre et
(inclus) ;
Le jour doit tre un entier entre et le nombre de jours contenus dans ce mois pour
cette anne-l.
Pour chacune de ces trois donnes, le programme doit demander lutilisateur dentrer
une valeur, en recommenant tant que la valeur nest pas conforme ces contraintes.
exemple :
Entrez
Entrez
Entrez
Entrez
Entrez

l'annee
le mois
le mois
le jour
le jour

(1900<=entier<=2011) : 2000
(1<=entier<=12) : 13
(1<=entier<=12) : 2
(1<=entier<=29) : 30
(1<=entier<=29) : 29

4 Calculs divers
Exercice 12
Dans date, crivez une fonction void ajoute_jour(t_date* date) qui ajoute un
jour la date passe en paramtre. Attention, votre fonction doit tenir compte du mois et aussi
de lanne (qui peut tre bissextile).
exemples :
Pour la date 01/01/2014, la fonction doit renvoyer 02/01/2014.
Pour la date 31/01/2014, la fonction doit renvoyer 01/02/2014.
Pour la date 28/02/2014, la fonction doit renvoyer 01/03/2014.
Pour la date 28/02/2012, la fonction doit renvoyer 29/02/2012.

Exercice 13
Dans date, crivez une fonction int calcule_duree(t_date date1, t_date
date2) qui calcule le nombre de jours entre les deux dates passes en paramtres. Notez
quil est possible dobtenir une valeur ngative, si date1 nest pas antrieure date2.
Pour cela, vous devez implmenter lalgorithme suivant :
Identifiez la date la plus petite, et en faire une copie.
Tant quon na pas atteint la date la plus grande, on incrmente simultanment :
o La date la plus petite ;
o Une variable entire utilise pour compter les jours.
Vous avez besoin des fonctions compare_dates, copie_date, et ajoute_jour.
exemples :
Pour les dates 01/01/2014 et 12/02/2014, la fonction doit renvoyer .
Pour les dates 10/01/2014 et 5/01/2014, la fonction doit renvoyer
.
Pour les dates 31/12/2013 et 01/01/2014, la fonction doit renvoyer .
Pour les dates 26/02/2014 et 05/03/2015, la fonction doit renvoyer
.
Pour les dates 26/02/2012 et 05/03/2013, la fonction doit renvoyer
.
Remarque : lalgorithme donn ici nest pas forcment trs efficaces du point de vue de
la rapidit du calcul, mais il a lavantage dtre simple implmenter.

Exercice 14
On veut reprsenter les recettes (i.e. largent gagn) dune entreprise pour chaque mois
dune anne. Pour cela, on utilise un tableau dont chaque lment contient une valeur
correspondant la recette mensuelle : janvier dans la 1re case, fvrier dans la 2me, etc.

TP 20

Algorithmique et programmation

3/4

manipulation de dates

Dans le fichier main.c, crivez une fonction void saisis_recettes(int recettes[])


qui reoit en paramtre un tableau vide suffisamment grand, et qui demande lutilisateur de
saisir la recette de chaque mois.
Contrainte : aucune variable entire ne doit tre utilise dans cette fonction ( part le
tableau recettes).
exemple :
Entrez la recette du mois de janvier : 1534
Entrez la recette du mois de fevrier : 12351
Entrez la recette du mois de mars : 5621
...

TP 20

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut

TP 21

Universit
Galatasaray

carrs latins

Prsentation
Le but de ce TP est dapprofondir les tableaux en manipulant des matrices dentiers
particulires, appele carrs latins. On aura pour cela recours la notion de type numr,
dj aborde dans des TP prcdents.

1 Dfinition
Un carr latin dordre est une matrice
dentiers compris entre
que chaque ligne et chaque colonne contient tous les entiers de
.
exemple : carr latin dordre :
[
On notera

, et tel

]
) dun carr latin

les lments (

et

Exercice 1
Cherchez manuellement un carr latin dordre , et un autre dordre .

Exercice 2
crivez une fonction void affiche_cl(int m[N][N]) qui affiche un carr latin m
dordre N. La constante N doit tre pralablement dclare, avec la valeur que vous voulez.
exemple : pour le carr latin de lexemple prcdent, on obtient :
0
0
2
3

1
0
3
2

2
3
0
1

3
2
1
0

Exercice 3
Pour tout entier , on peut construire un carr latin dordre

par permutation circulaire :

crivez une fonction void genere_cl_permutation(int m[N][N]) qui prend en


argument une matrice dordre N, et qui initialise cette matrice pour obtenir un carr latin en
utilisant le principe dcrit ci-dessus.

TP 21

Algorithmique et programmation

1/4

carrs latins

exemple : pour N=10, on obtient la matrice suivante :


0
1
2
3
4
5
6
7
8
9

1
2
3
4
5
6
7
8
9
0

2
3
4
5
6
7
8
9
0
1

3
4
5
6
7
8
9
0
1
2

4
5
6
7
8
9
0
1
2
3

5
6
7
8
9
0
1
2
3
4

6
7
8
9
0
1
2
3
4
5

7
8
9
0
1
2
3
4
5
6

8
9
0
1
2
3
4
5
6
7

9
0
1
2
3
4
5
6
7
8

2 Ronds & croix


On veut maintenant tester si une matrice donne est bien un carr latin. Il est pour cela
ncessaire dcrire plusieurs fonctions effectuant des traitements secondaires. Au cours de ces
traitements, on a besoin de distinguer deux types de valeurs, que lon va reprsenter par deux
symboles : croix () et rond ().

Exercice 4
Dfinissez un type numr t_symbole contenant les valeurs croix et rond.

Exercice 5
crivez une fonction void initialise_ronds_vecteur(t_symbole tab[N]) qui
initialise le tableau pass en paramtre avec la valeur rond.

Exercice 6
crivez une fonction int compte_ronds_vecteur(t_symbole tab[N]) qui
renvoie le nombre dlments gaux rond dans le tableau pass en paramtre.
exemple : pour le tableau {rond,croix,croix,croix,rond,rond}, on obtient la
valeur .

Exercice 7
crivez une fonction int contient_rond_vecteur(t_symbole tab[N]) qui
dtermine si le tableau pass en paramtre contient au moins un lment gal rond. Si cest
le cas, la fonction renvoie , sinon elle renvoie .
exemples :
Pour le tableau {rond,croix,croix,croix,rond,rond}, on obtient la valeur
.
Pour le tableau {croix,croix,croix,croix,croix,croix }, on obtient la
valeur .
Remarque : pensez utiliser la fonction prcdente.

3 Test de proprit
On propose une mthode permettant de vrifier quune matrice carre est bien un carr
latin.
Pour chaque ligne dindice :
o On initialise un tableau
avec ronds.
o On parcourt la ligne numro
de la matrice
, et pour chaque
coefficient
:
On place une croix dans la case numro
de
.

TP 21

Algorithmique et programmation

2/4

carrs latins

o Si, aprs avoir trait toute la ligne, le tableau


contient toujours au
moins un rond, alors la ligne numro ne contient pas tous les entiers
compris entre et
, et nest pas un carr latin.
o Sinon (aucun rond), alors on passe la ligne suivante.
Si toutes les lignes sont correctes, alors fait la mme chose avec les colonnes.
Si toutes les colonnes sont elles-aussi correctes, alors il sagit bien dun carr latin.

exemple : on considre la matrice suivante :


[

Pour la ligne , on obtient le tableau {croix,croix,croix,croix}. Il ne reste


pas de rond, car cette ligne contient tous les entiers de .
Pour la ligne 1, on obtient le tableau {rond,croix,croix,croix}. Il reste un
rond dans lemplacement du tableau, car la ligne ne contient pas de valeur .
Pour la ligne , on obtient le tableau {croix,rond,croix,croix}, car cette
fois cest la valeur qui manque.
Pour la ligne , on obtient le tableau {croix,rond,croix,rond}, car la fois
et manquent.

Exercice 8
crivez une fonction int teste_vecteur(int m[N][N], int pos, int ligne)
qui reoit une matrice carre m et une position pos. La position est une valeur comprise entre
et
, et indiquant le numro dune ligne ou dune colonne de m. Le dernier paramtre
ligne indique si on doit considrer la ligne numro pos (quand ligne vaut ), ou bien la
colonne numro pos (quand ligne vaut ). La fonction doit appliquer la mthode dcrite cidessus sur la ligne/colonne concerne. Elle renvoie si la ligne/colonne est valide, i.e. si elle
contient toutes les valeurs entre et
. Sinon, elle renvoie .
exemples : pour la matrice prcdente, on obtient les rsultats suivants :
Lappel teste_vecteur(m,0,1) renvoie ;
Lappel teste_vecteur(m,1,1) renvoie ;
Lappel teste_vecteur(m,2,1) renvoie ;
Lappel teste_vecteur(m,0,0) renvoie ;

Exercice 9
crivez une fonction int est_carre_latin(int m[N][N]) qui teste si la matrice
spcifie est un carr latin. La fonction doit bien sr utiliser teste_vecteur. Elle renvoie
si la matrice est bien un carr latin, et sinon.

4 Orthogonalit
Soient
( )et
( ) (
) deux carrs latins dordre . On appelle
matrice produit de par la matrice note
=(
), dont chaque terme est une
paire dun lment de et dun lment de .
Attention : il ne sagit pas du produit matriciel classique. De plus, la matrice produit
obtenue est carre et de dimensions
.
On dit que deux carrs latins et
sont orthogonaux si la matrice produit
ne
contient pas deux fois le mme lment. La matrice produit obtenue est alors appele carr
bi-latin (ou grco-latin) dordre .
TP 21

Algorithmique et programmation

3/4

carrs latins

exemples : soient les carrs latins suivants :


[

],

],

On a alors les produits suivants :

] : les couples (

[
donc les carrs latins

et

sont orthogonaux, et

) sont tous distincts,


est un carr bi-latin.

] : les carrs latins

et

ne sont pas

orthogonaux car certains couples tel que


apparaissent deux fois dans la
matrice produit
. Donc, cette matrice produit nest pas un carr bi-latin.

Exercice 10
Cherchez manuellement deux carrs latins orthogonaux dordre .

Exercice 11
crivez les fonctions initialise_ronds_matrice, compte_ronds_matrice, et
contient_rond_matrice qui utilisent respectivement initialise_ronds_vecteur,
compte_ronds_vecteur, et contient_rond_vecteur pour effectuer le mme
traitement sur des matrices de croix/ronds (au lieu de simples vecteurs).

Exercice 12
On peut gnraliser lalgorithme de la section prcdente pour tester lorthogonalit de
deux carrs latins :
On initialise une matrice avec des ronds.
Pour chaque valeurs de et (
):
o On place une croix dans la case de
situe sur la ligne
et sur la
colonne .
Si, aprs avoir trait toutes les valeurs de i et j, la matrice
contient toujours au
moins un rond, alors la matrice produit
ne contient pas tous les couples
possibles, et ne sont pas orthogonaux et
nest pas un carr bi-latin.
crivez une fonction int sont_orthogonaux(int a[N][N], int b[N][N]) qui
implmente lalgorithme ci-dessus pour tester si deux carrs latins sont orthogonaux.

TP 21

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 22

reprsentation dune promotion

Prsentation
Le but de ce TP est de crer une base de donnes simple, permettant de dcrire une
promotion dtudiants. Pour cela, nous allons utiliser des types structure et numr. Certains
ont dj t crs lors de TP prcdents et sont disponibles dans la bibliothque date fournie
avec ce sujet. Les autres sont crer lors de ce TP, dans une nouvelle bibliothque
promotion. La bibliothque chaine, qui permet de manipuler des chanes de caractres, est
aussi fournie avec le sujet et sera utilise dans la dernire partie du TP.

1 Reprsentation dun tudiant


Exercice 1
Crez les fichiers ncessaires la dfinition dune bibliothque appele promotion.
Cette bibliothque doit tre configure pour elle-mme utiliser les bibliothques date et
chaine fournies avec ce sujet. Crez aussi un fichier principal main.c qui permettra de
tester les fonctions que vous crirez. Notez que dans les deux premires parties du TP, vous
navez pas besoin dutiliser les fonctions de la bibliothque chaine.

Exercice 2
Dans promotion, dfinissez un type numr t_genre permettant de reprsenter le genre
dune personne : soit fminin, soit masculin.

Exercice 3
Dans promotion, dfinissez un type structure t_etudiant permettant de reprsenter un
tudiant par son nom, son prnom, sa date de naissance et son genre. Vous devez bien entendu
utiliser les types t_date et t_genre pour les deux derniers champs. Vous dfinirez une
constante TAILLE_MAX_NOM pour dterminer le nombre de caractres maximal quun nom ou
prnom peut contenir.

Exercice 4
Dans promotion, crivez une fonction saisis_etudiant permettant lutilisateur de
saisir un tudiant.
exemples :
Entrez le prnom : Emre
Entrez le nom : Emreoglu
Date de naissance :
Entrez le jour : 20
Entrez le mois : 11
Entrez lanne : 1985
Entrez le genre : 1
Entrez le prnom : Zeynep

Entrez le nom : ztrk


Date de naissance :
Entrez le jour : 12
Entrez le mois : 4
Entrez lanne : 1988
Entrez le genre : 0

Exercice 5
Dans promotion, crivez une fonction affiche_etudiant qui affiche un tudiant pass
en paramtre.

TP 22

Algorithmique et programmation

1/3

reprsentation dune promotion

exemples :
Pour Emre de lexemple prcdent :
Emre Emreoglu, n le 20 novembre 1985

Pour Zeynep de lexemple prcdent :

Zeynep ztrk, ne le 12 avril 1988

Attention : reproduisez bien laccord du participe pass du verbe natre !

2 Reprsentation dune promotion


Exercice 6
Une promotion correspond un ensemble dtudiants. Dans promotion, dfinissez un
type structure t_promo permettant de reprsenter un groupe dtudiants grce un tableau
etudiants. La taille maximale de la promotion devra tre fixe grce une constante
TAILLE_MAX_PROMO. La taille effective de la promotion (i.e. combien dlments du tableau
sont utiliss pour reprsenter la promotion) devra tre reprsente sous la forme dun champ
taille.

Exercice 7
Dans promotion, crivez une fonction saisis_promotion permettant de saisir les
tudiants dune promotion. Aprs avoir entr les donnes concernant un tudiant, lutilisateur
devra avoir la possibilit darrter la saisie.
exemple :
-- Etudiant n.0 -Entrez le prnom : Emre
Entrez le nom : Emreoglu
Date de naissance :
Entrez le jour : 20
Entrez le mois :
11
Entrez lanne : 1985
Entrez le genre : 1
Voulez-vous saisir un autre etudiant (O/N) ? O
-- Etudiant n.1 -Entrez le prnom : Zeynep
Entrez le nom : ztrk
Date de naissance :
Entrez le jour : 12
Entrez le mois : 4
Entrez lanne : 1988
Entrez le genre : 0
Voulez-vous saisir un autre etudiant (O/N) ? O
-- Etudiant n.2 -Entrez le prnom : Can
Entrez le nom : Demirkesen
Date de naissance :
Entrez le jour : 8
Entrez le mois :
8
Entrez lanne : 1984
Entrez le genre : 1
Voulez-vous saisir un autre etudiant (O/N) ? N
3 etudiants ont t saisis.

Exercice 8
Dans promotion, crivez une fonction affiche_promotion qui affiche toute la
promotion passe en paramtre.
exemple :
0. Emre Emreoglu, n le 20 novembre 1985
1. Zeynep ztrk, ne le 4 avril 1988
2. Can Canoglu, n le 8 aot 1984

TP 22

Algorithmique et programmation

2/3

reprsentation dune promotion

3 Recherche dans la promotion


Pour effectuer des recherches, nous allons utiliser les fonctions de la bibliothque
chaine, qui permet de manipuler des chaines de caractres et qui a t crite lors dun TP
prcdent.

Exercice 9
Pour gagner du temps, dans le reste du TP, la promotion ne sera pas initialise en utilisant
la fonction saisis_promo, mais plutt directement dans le programme, en utilisant la
syntaxe qui permet dinitialiser une variable de type structure lors de sa dclaration.
Dans promotion, crivez une fonction t_promo initialise_promotion() qui
renvoie une variable de type t_promo contenant les tudiants suivants :
Nom
Prnom Date de naissance Genre
Emreolu
Emre
20/11/1985
Masculin
ztrk
Zeynep
08/08/1988
Fminin
zanolu
zan
10/10/1986
Masculin
Canolu
Can
08/08/1984
Masculin
Kk
Naz
02/02/1985
Fminin
Kkkarakurt Dilek
07/07/1985
Fminin
Onay
Sevgi
04/04/1985
Fminin
Koak
Ozgur
06/05/1985
Masculin
Kk
Hakan
03/03/1986
Masculin
Remarque : copiez-collez directement le tableau dans Eclipse, puis adaptez pour que le
texte obtenu soit conforme la syntaxe du C.

Exercice 10
dans promotion, crivez une fonction void cherche_homonymes(t_promo p,
char* nom) qui cherche dans la promotion p les tudiants qui ont exactement le nom nom, et
qui les affiche. La fonction ne renvoie rien du tout, elle se contente dafficher les tudiants
trouvs.
exemple : rsultat de la recherche de "Kucuk"
Rsultat de la recherche pour la chane "Kucuk" :
- Naz Kucuk, ne le 2 fvrier 1985
- Hakan Kucuk, n le 3 mars 1986

Exercice 11
Dans promotion, crivez une fonction cherche_prefixe(t_promo p, t_promo*
res, char* prefixe) qui reoit en paramtres deux promotions p et res, et une chane
de caractres prefixe.
La fonction doit chercher dans p les tudiants dont le nom est prfix par prefixe, mais
cette fois sans les afficher. La promotion res (passe par adresse) est suppose initialise,
mais vide : la fonction doit remplir cette promotion avec les tudiants dont le nom est prfix
par prefixe. Le rsultat est donc renvoy par adresse, travers res.
exemple : si on affiche, en utilisant affiche_promo depuis la fonction main, le rsultat
de la recherche de "Kucuk", on obtient :
0. Naz Kucuk, ne le 2 fvrier 1985
1. Dilek Kucukkarakurt, ne le 7 juillet 1985
2. Hakan Kucuk, n le 3 mars 1986

TP 22

Algorithmique et programmation

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 23

partition dun entier

Prsentation
Le but de ce TP est dapprofondir la manipulation des structures et des pointeurs sur ces
structures.

1 Dfinition et reprsentation
(
) finie et dcroissante
On appelle partition dun entier une suite
dentiers se terminant par , et telle que
. La valeur
reprsente
la longueur de cette partition (le zro final nest pas compt).
exemples : quelques partitions de lentier
(
) est une partitions de longueur , puisque

.
(
) est une partition de longueur , puisque :

.
(
) est une partition de longueur .

Exercice 1
En langage C, nous allons reprsenter une partition par une structure contenant deux
champs :
Lentier concern ;
La suite correspondant sa partition, et reprsente sous forme dun tableau
dentiers termin par un zro ;
Dfinissez une constante L_MAX correspondant la longueur maximale dune partition.
Puis, dfinissez un type structur t_partition contenant les champs lists ci-dessus, en
utilisant L_MAX.
exemples : une variable de type t_partition pourra tre initialise la dclaration de
manire dcrire les partitions de lexemple prcdent, en procdant de la faon suivante :
t_partition p1 = {12, {4,4,3,1,0}};
t_partition p2 = {12, {5,4,3,0}};
t_partition p3 = {12, {12,0}};

Exercice 2
crivez une fonction void affiche_partition(t_partition p) qui affiche la
partition p passe en paramtre. Vous devez obtenir un affichage de la forme indique dans
lexemple ci-dessous.
exemple : pour les partitions de lexemple prcdent, on obtient :
12 = 4 + 4 + 3 + 1
12 = 5 + 4 + 3
12 = 12

Exercice 3
crivez une fonction void copie_partition(t_partition p, t_partition*
copie) qui copie la partition p dans copie. Attention, chaque valeur originale de p doit tre
copie individuellement dans la variable copie.

TP 23

Algorithmique et programmation

1/3

partition dun entier

2 Comparaison
On peut dfinir un ordre appel ordre lexicographique sur les partitions dun entier .
Pour comparer les deux partitions
(
) et
(
), on applique
la rgle suivante :
Sil existe un entier tel que :
,
, ,
et
,
alors :
o Si
, on a
.
o Si
, on a
.
Sinon, c'est--dire si
et
pour tout , alors on a
.
exemples : comparaison de quelques partitions de lentier
:
(
) (
) (
) (
) (
) (
)

Exercice 4
crivez une fonction int compare_partitions(t_partition p1, t_partition
p2) qui utilise la rgle explique ci-dessus pour comparer les partitions p1 et p2. La fonction
renvoie une valeur positive si
, nulle si
et ngative si
.
exemples :
) et (
), la fonction renvoie une valeur positive ;
Pour (
) et (
), la fonction renvoie zro ;
Pour (
) et (
), la fonction renvoie une valeur ngative.
Pour (
Remarque : on supposera que les deux partitions passes en paramtres concernent toutes
les deux le mme entier .

3 Partitions triviales
On peut distinguer deux partitions triviales pour tout entier
:
La partition triviale courte, que lon notera , est la partition de longueur
entier, i.e.
(
).
La partition triviale longue, que lon notera , est la partition de longueur
entier, i.e.
(
).
exemples : pour
, les deux partitions triviales sont
(
(
).
Remarque : pour toute partition dun entier , on a la proprit
.

de cet
de cet
)

et

Exercice 5
crivez une fonction void calcule_partition_courte(int n, t_partition
*p) qui calcule la partition triviale courte de n et place le rsultat dans le paramtre p pass
par adresse.

Exercice 6
Mme chose avec la fonction void
t_partition *p) qui calcule .

calcule_partition_longue(int

n,

4 Gnration
Exercice 7
Si est la partition dun entier , on peut calculer la partition
lexicographique laide de lalgorithme suivant :
Tant quil existe un entier tel que
:

TP 23

Algorithmique et programmation

qui prcde

dans lordre

2/3

partition dun entier

On pose :
o
o
On calcule lentier gal au nombre de dans la partition , c'est--dire lentier
tel que :
On calcule le quotient et le reste de la division euclidienne de
par , et
on pose :
o
o
(si
)
On ajoute un comme dernier terme de la suite .

exemple : on considre deux partitions de


(
)

o Alors :
,
,
,
(
).
o Donc :
(
)

o Alors :
,
,
,
(
).
o Donc :

:
et

et

En appliquant manuellement cet algorithme, calculez les partitions de


prcdent les partitions :
(
)
(
)
).
(

qui

Exercice 8
crivez une fonction void calcule_partition_suivante(t_partition p0,
t_partition* p1) qui calcule la partition p1 suivant p0 dans lordre lexicographique, en
utilisant lalgorithme prcdent.

Exercice 9
En utilisant les fonctions prcdentes, crivez une fonction void affiche_toutes_
partitions(int n) qui calcule et affiche toute les partitions de lentier n dans lordre
lexicographique.
exemple : pour
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9

TP 23

=
=
=
=
=
=
=
=
=
=
=
=
=
=
=

(
(
(
(
(
(
(
(
(
(
(
(
(
(
(

9
8
7
7
6
6
6
5
5
5
5
5
4
4
4

)
1
2
1
3
2
1
4
3
2
2
1
4
3
3

)
)
1
)
1
1
)
1
2
1
1
1
2
1

)
)
1 )
)
)
1 )
1 1 )
)
)
1 )

9
9
9
9
9
9
9
9
9
9
9
9
9
9
9

=
=
=
=
=
=
=
=
=
=
=
=
=
=
=

(
(
(
(
(
(
(
(
(
(
(
(
(
(
(

Algorithmique et programmation

4
4
4
3
3
3
3
3
3
3
2
2
2
2
1

2
2
1
3
3
3
2
2
2
1
2
2
2
1
1

2
1
1
3
2
1
2
2
1
1
2
2
1
1
1

1
1
1
)
1
1
2
1
1
1
2
1
1
1
1

)
1 )
1 1 )
)
1
)
1
1
1
1
1
1
1
1

)
)
1
1
)
1
1
1
1

)
1 )
)
1 )
1 1 )
1 1 1 )

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 24

rotation dun carr

Prsentation
Le but de ce TP est dapprofondir la manipulation des matrices et des structures. Pour
cela, nous allons tracer un carr et lui faire subir des rotations.
Ce TP utilise la SDL, mais ne le configurez pas encore pour la SDL maintenant. Attendez
plutt lexercice ncessitant la SDL, afin de pouvoir bnficier avant cela de la sortie texte
pour dboguer les premires fonctions.

1 Matrice de rotation
Exercice 1
crivez une fonction affiche_matrice qui affiche comme dans lexemple ci-dessous
un tableau de rels de type double, reprsentant une matrice
.
exemple : pour la matrice {{-1,-2},{3,4}}, on doit obtenir exactement laffichage
suivant (utilisez le format appropri dans printf) :
( -1.000000 -2.000000 )
( 3.000000 4.000000 )

Exercice 2
On rappelle que la matrice de rotation dangle scrit :
cos
(
)
cos
Dfinissez une constante PI pour reprsenter
(
). Puis, crivez une
fonction initialise_rotation qui initialise une matrice passe en paramtre, de manire
ce quelle reprsente la rotation dangle , lui aussi pass en paramtre.
, on obtient la matrice suivante :
exemple : pour langle
(
(

0.500000 -0.866025 )
0.866025 0.500000 )

Remarque : dans cet exercice on a besoin dutiliser les fonctions cosinus et sinus. Elles
sont implmentes sous la forme des fonctions cos et sin dfinies dans la bibliothque
math.h. Vous devez, bien entendu, configurer votre projet de manire utiliser cette
bibliothque. Notez que ces fonctions prennent en paramtre un angle exprim en radians.

2 Rotation dun vecteur


Exercice 3
Dfinissez une structure s_vecteur reprsentant un vecteur dans un espace
dimensions, i.e. un vecteur dcrit par deux coordonnes relles et .

Exercice 4
crivez une fonction affiche_vecteur qui affiche un vecteur en respectant exactement
la forme dcrite dans lexemple ci-dessous.
exemple : affichage du vecteur {0,-1} :
TP 24

Algorithmique et programmation

1/4

rotation dun carr

( 0.000000 )
( -1.000000 )

Exercice 5
crivez une fonction void applique_rotation(double m[2][2], struct
s_vecteur v, struct s_vecteur* resultat) qui prend en paramtre un vecteur v et
une matrice de rotation m, et calcule les coordonnes du vecteur image. Ce rsultat est renvoy
via le paramtre resultat.
exemple : pour la matrice et le vecteur des exemples prcdents, on obtient :
( 0.866025 )
( -0.500000 )

3 Rotation dun carr


Exercice 6
On peut calculer les coordonnes des 4 sommets dun carr
de son centre
et des coordonnes du vecteur
sommet :

partir des coordonnes


au
), qui relie le centre

On a alors :

et

et

Les coordonnes du vecteur


sobtiennent par rotation dangle et de centre

vecteur
, donc :

et

On en dduit alors les coordonnes des sommets et .

du

laide de ces remarques, crivez une fonction void dessine_carre(int x_O, int
y_O, struct s_vecteur v_OA, Uint32 coul) qui dessine lcran le carr
dfini par son centre le vecteur .
Remarque : pensez utiliser la fonction dessine_segment de la bibliothque
graphisme.
exemple : pour le centre
et le vecteur
, on obtient la
figure suivante :

TP 24

Algorithmique et programmation

2/4

rotation dun carr

Exercice 7
On veut maintenant animer ce carr, en le faisant tourner autour de son centre . crivez
une fonction void tourne_carre(int x_O, int y_O, struct s_vecteur v_OA,
Uint32 coul, int k) qui fait tourner dun tour complet le carr
en appliquant

chaque tape une rotation dangle au vecteur


:

Lalgorithme est le suivant :


Tant quon na pas fait un tour complet,
1. Tracer le carr en rouge ;
2. Attendre un certain temps correspondant la constante DELAI dfinie dans
la bibliothque graphisme (et exprim en ms) ;
3. Tracer le mme carr en noir (pour effacer le carr rouge)
4. Calculer le nouveau carr en effectuant la rotation dangle .
5. Recommencer.
Testez votre fonction avec plusieurs valeurs de . Vous remarquerez que lanimation
obtenue nest pas trs fluide : ceci est d au fait que nous nutilisons pas de tampon (ou
buffer). Nous aborderons ce point dans un futur TP.

Exercice 8
Faites une copie de la fonction prcdente, que vous appellerez tourne_carre2. Dans
cette fonction effectuez les modifications suivantes :
Supprimez ltape 3 de lalgorithme prcdent ;
Limitez la rotation totale un quart-de-tour au lieu dun tour complet (i.e. au
lieu de ) ;

TP 24

Algorithmique et programmation

3/4

rotation dun carr

Supprimez le paramtre coul, et recalculez la couleur chaque itration. Partez


dune couleur purement rouge (donc
,
,
) et augmentez les
composantes verte et bleu de
chaque itration (par consquent, la
dernire itration, la couleur utilise sera le blanc).

Remarque : pensez utiliser la fonction convertis_rvb de la bibliothque


graphisme.
Vous devez obtenir une figure ressemblant ceci :

TP 24

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 25

zoom dune image

Prsentation
Le but de ce TP est dimplmenter des fonctions permettant de modifier la taille
(graphique) dune image. Ceci ncessitera de traiter des matrices reprsentant ces images.

1 Prparation
Larchive fournie avec le sujet contient un album dimages dj utilises dans certains TP
prcdents, ainsi que la bibliothque graphisme, elle aussi dj utilis. Elle a t complte
de certaines fonctions particulires spcialement pour ce TP, cf. le code source. Vous aurez
tout particulirement besoin des fonctions suivantes :
charge_image : charge un fichier contenant une image, et la renvoie sous la forme
de surface.
sauve_surface : enregistre une surface sous la forme dun fichier image.
dessine_surface : affiche une dans la fentre principale.
initialise_surface : cre une nouvelle surface (image) vide.
Des variantes de fonctions utilises dans les TP prcdents, qui travaillent sur une
surface passe en paramtre au lieu de travailler sur la fentre principale. Leur
nom se termine en _surface. Exemples : allume_pixel_surface,
couleur_pixel_surface, etc.
Une bonne partie de ce TP consiste manipuler des images, sous la forme de variables de
type SDL_Surface. Vous avez besoin de savoir que ce type est une structure, dont les champs
w et h correspondent respectivement la largeur (width) et la hauteur (height) de limage
concerne. Vous pouvez lire ces champs, mais pas les modifier.

Exercice 1
Toutes vos fonctions doivent tre crites dans le fichier main.c. crivez dabord une
fonction void trace_surface(SDL_Surface surface) qui reoit une surface (donc une
image) en paramtre. La fonction doit :
1) Effacer la fentre principale ;
2) Afficher limage surface partir du point ( ) ;
3) Attendre que lutilisateur appuie sur une touche.

Exercice 2
Compltez la fonction main pour afficher lune des photos fournies avec le sujet. Vous
aurez besoin dutiliser charge_image et trace_surface.

2 Agrandissement
Une mthode lmentaire pour faire un zoom grossissant (zoom in) dun facteur dune
image ( est un entier), consiste transformer chaque pixel de limage initiale en un carr de
pixels o tous les pixels ont exactement la mme couleur que le pixel initial.

TP 25

Algorithmique et programmation

1/4

zoom dune image

Une image ne peut pas toujours tre entirement zoome et affiche lcran, car il est
possible quelle soit trop grande. Pour cette raison, dans ce TP on ne zoome quune partie de
limage initiale, appele zone dintrt. Celle-ci est dfinie par lutilisateur, de manire ne
pas tre plus grande que la fentre dans laquelle on va ensuite dessiner (sinon, cela
provoquera une erreur dexcution).

Considrons par exemple la figure suivante. Limage de gauche est limage originale. La
zone dintrt est dfinie par son coin suprieur gauche et par ses dimensions. Ici, on a
), et les dimensions respectives
slectionn le point de coordonnes (
et
pixels pour la largeur et la hauteur. De plus, on a agrandit limage par un facteur . En
appliquant le principe expliqu ci-dessus, on obtient limage de droite.
=

Zone dintrt

Exercice 3
crivez la fonction den tte SDL_Surface* agrandis(SDL_Surface* source, int x,
int y, int largeur, int hauteur, int coef), o source pointe sur la surface
zoomer, x et y sont les coordonnes du coin suprieur gauche de la zone dintrt, largeur et
hauteur sont ses dimensions, et coef est le coefficient dagrandissement.
La fonction doit crer une nouvelle surface destine contenir le rsultat de
lagrandissement. Lagrandissement est ralis en traitant individuellement chaque pixel de la
zone dintrt :
Lire la couleur du pixel original (dans source) ;
Allumer dans la nouvelle surface autant de pixels de mme couleur quil est
ncessaire.
Dans lexemple prcdent, limage de droite est obtenue en effectuant lappel
agrandis(photo,70,70,200,150,4) sur la surface reprsentant limage de gauche.

Exercice 4
Compltez la fonction main de manire :

TP 25

Algorithmique et programmation

2/4

zoom dune image

4) Afficher un rectangle correspondant la zone dintrt (comme dans limage de


gauche de la figure prcdente) ;
5) Attendre que lutilisateur appuie sur une touche ;
6) Agrandir la photo charge prcdemment ;
7) Afficher le rsultat de cet agrandissement lcran (toujours en utilisant
trace_surface) ;
8) Enregistre (grce sauve_surface) le rsultat de lagrandissement sous la forme
dun fichier bitmap de nom imagex.zoomin.bmp, o x correspond au numro du
fichier dimage ;
9) Attendre que lutilisateur appuie sur une touche.
Remarque : attention aux paramtres que vous utilisez. Si limage obtenue la suite de
lagrandissement est trop grande, elle ne rentrera pas dans la fentre, et cela provoquera donc
une erreur dexcution quand vous essaierez de lafficher.

3 Rduction
On peut appliquer un principe similaire pour rduire une image (zoom out). La diffrence
est que cette fois, il y a une perte dinformation : la rsolution de limage tant moins bonne,
certains pixels doivent tre supprims. Une faon nave de procder est de substituer un
groupe de pixels, un seul pixel dont la couleur est la moyenne des couleurs originales. Ce
principe est illustr dans la figure ci-dessous. Ainsi, les blocs de pixels jaunes et pixel
rouge deviennent chacun pixel orange.
:

Bien sr, contrairement lagrandissement, il ny a pas de problme avec la dimension de


limage, et la rduction sapplique lintgralit de limage (il ny a pas de zone dintrt).
Pour lexemple prcdent, en rduisant par un facteur de , on obtient ainsi le rsultat
suivant :

Remarque : par souci de simplicit, on nutilisera que des coefficients de rduction qui
sont des diviseurs des dimensions de limage.

Exercice 5
TP 25

Algorithmique et programmation

3/4

zoom dune image

crivez la fonction SDL_Surface* reduis(SDL_Surface* source, int coef), o


source pointe sur la surface zoomer et coef est le coefficient de rduction. La fonction
renvoie une nouvelle surface, plus petite, contenant la version rduite de source.

Exercice 6
Compltez la fonction main pour :
10) Afficher limage originale nouveau ;
11) Calculer la version rduite de limage avec reduis ;
12) Enregistrer cette image sous le nom imagex.zoomout.bmp ;
13) Attendre que lutilisateur appuie sur une touche.
Remarque : ces actions viennent complter les actions dj programmes dans la
fonction main.

Exercice 7
crivez une fonction SDL_Surface* reduis_agrandis(SDL_Surface* source, int
coef) qui :
Rduit la surface source dun facteur coef ;
Applique la surface obtenue un agrandissement quivalent.
On obtient alors une image de mme taille que limage originale. La fonction doit
renvoyer cette image sous la forme dun pointeur sur une nouvelle surface, comme dans les
fonctions prcdentes.

Exercice 8
Compltez la fonction main pour :
14) Afficher limage originale nouveau ;
15) Calculer la version rduite-agrandie de limage avec reduis_agrandis ;
16) Enregistrer cette image sous le nom imagex.zoomoutin.bmp ;
17) Attendre que lutilisateur appuie sur une touche.
Visualiser limage originale et imagex.zoomoutin.bmp : vous devriez visualiser la perte
dinformation subie lors de la rduction, et mentionne dans les explications concernant la
rduction.
Remarque : comme leur numrotation lindique, ces actions viennent complter les
actions dj programmes dans la fonction main.

TP 25

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 26

automates finis

Prsentation
Le but de ce TP est dapprofondir lutilisation des types structurs et des matrices, via
ltude dautomates finis. Tous les types et fonctions devront tre crits dans le fichier
main.c.

1 Dfinition
Un automate fini est un modle mathmatique d'ordinateur trs simple, capable de
reconnatre des mots forms de lettres contenus dans un alphabet prdfini et respectant une
certaine structure. On appelle longueur dun mot le nombre de lettres qui le composent. On
note le mot de longueur , appel mot vide.
{
}, on peut produire des mots composs de et de ,
exemple : avec l'alphabet
tels que ,
,
, etc.
Les automates les plus simples ont une sortie binaire : tout mot est soit accept par
lautomate, soit refus. On peut reprsenter un automate par un graphe orient :
Chaque nud s'appelle un tat ;
Chaque lien est un changement dtat, associ une lettre de l'alphabet.
exemple : soit lautomate reprsent par le graphe suivant :

Cet automate comporte 4 tats , ,


et :
L'tat
reprsent en bleu est un tat initial.
L'tat
reprsent en rouge un tat acceptant
Les tats
,
et
sont des tats refusant.
Les liens de cet automate sont associs aux lettres ou , ce qui signifie quil est dfini
}.
pour lalphabet {
En parcourant le graphe dun automate depuis lun de ses tats initiaux, on peut dcider
quels sont les mots quil accepte. Ce parcours est ralis de la faon suivante :
1. On dmarre dun tat initial, qui devient ltat courant.

TP 26

Algorithmique et programmation

1/4

automates finis

2. On considre chaque lettre constituant le mot, en commenant par la 1re. chaque


fois, on se dplace dans lautomate en suivant le lien associ la lettre considre.
3. Si le parcours se termine sur un tat acceptant, alors le mot est accept. Sinon, il
est refus.
exemple : dans notre graphe dexemple, on na quun seul tat initial
, donc tout
parcours dmarre obligatoirement de ce nud. On na quun seul tat acceptant , donc tout
mot accept se termine obligatoirement sur ce nud.
Quelques mots accepts par cet automate, avec le parcours correspondant :
o
:
o
:
o
:
Quelques mots refuss par cet automate :
o
:
o
:
o
:
On peut dmontrer que l'ensemble des mots accepts par cet automate sont les mots de
longueur au moins gale et qui commencent et se terminent par la lettre .
On peut reprsenter un automate sous la forme dune matrice de transition, qui indique les
changements possibles pour chaque lettre, partir de chaque tat.
exemple : pour lautomate prcdent, on a la matrice de transition suivante :

Dans ce TP, on veut implmenter un automate de ce type. Pour simplifier le problme, on


fera les hypothses suivantes :
Lautomate ne contient quun seul tat initial et un seul tat acceptant ;
{
};
Lalphabet est toujours
La longueur du mot trait est constante.

2 Implmentation
Exercice 1
Dans main.c, dfinissez les trois constates suivantes, utiliser dans le reste du TP :
LONGUEUR_MAX_MOT : longueur maximale dun mot (valeur laisse votre
choix) ;
NB_MAX_ETATS : nombre maximal dtats autoris pour un automate (utilisez
une valeur suprieure ou gale pour ce TP) ;
TAILLE_ALPHABET : nombre de lettres dans lalphabet (utilisez , puisque
} dans ce TP).
notre alphabet est toujours {

Exercice 2
On reprsente un automate en mmoire l'aide d'une structure contenant
nb_etats : nombre d'tats de l'automate ;
etat_initial : numro de ltat initial ;

TP 26

Algorithmique et programmation

champs :

2/4

automates finis

etat_acceptant : numro de l'tat acceptant ;


matrice_transition : matrice de transition.
Dans main.c, dfinissez un type structur appel t_automate, qui contient ces

champs.

Exercice 3
crivez la fonction void affiche_automate(t_automate a) qui affiche les
champs de l'automate a pass en paramtre.
Pour tester votre fonction, initialisez dans la fonction main un automate correspondant
lexemple prcdent. Vous devez effectuer une initialisation la dclaration, i.e. en utilisant la
syntaxe base daccolades {...} vue en cours.
exemple : si l'automate pass en argument est celui de l'exemple prcdent, on obtiendra
exactement l'affichage ci-dessous :
Le nombre d'etats de l'automate est 4
L'etat initial est E0
L'etat acceptant est E2
La matrice de transition est :
a
b
E0
E1
E3
E1
E2
E1
E2
E2
E1
E3
E3
E3

Exercice 4
crivez la fonction void saisis_automate(t_automate* a) qui demande
lutilisateur de saisir les diffrents champs constituant un automate. Les valeurs saisies sont
utilises pour initialiser lautomate pass en paramtre.
exemple :
Entrez le nombre d'etats : 4
Entrez l'etat initial : 0
Entrez l'etat acceptant : 2
- Entrez les transitions de letat
a : 1
b : 3
- Entrez les transitions de letat
a : 2
b : 1
- Entrez les transitions de letat
a : 2
b : 1
- Entrez les transitions de letat
a : 3
b : 3

E0 :
E1 :
E2 :
E3 :

Exercice 5
crivez

une

etat_courant,

int
applique_transition(t_automate
a,
int
lettre), qui reoit en paramtres ltat courant, i.e. ltat

fonction
char

actuellement occup, et une lettre de l'alphabet . La fonction calcule et retourne lentier


correspondant l'tat obtenu en suivant le lien associ la lettre partir de ltat courant, tel
que dcrit dans la matrice de transition de lautomate.
Remarque : cette fonction s'appelle la fonction de transition de l'automate. Son
implmentation tient en une seule ligne.
exemples :
L'appel applique_transition(a,1,'a') renvoie la valeur .
L'appel applique_transition(a,1,'b') renvoie la valeur .
L'appel applique_transition(a,2,'b') renvoie la valeur 1.

TP 26

Algorithmique et programmation

3/4

automates finis

L'appel applique_transition(a,3,'b') renvoie la valeur 3.

Exercice 6
crivez une fonction void teste_mot(t_automate a) qui ralise les oprations
suivantes :
1. Afficher lautomate reu en paramtre ;
2. Demander l'utilisateur de saisir une chaine de caractres contenant seulement des
lettres de lalphabet ;
3. Tester si le mot reprsent par cette chaine de caractres est accept ou pas par
l'automate.
4. Afficher le rsultat de ce test.
Testez votre programme avec lautomate donn en exemple.

Exercice 7
Mme chose avec lautomate suivant :
,

Testez lautomate avec les mots suivants :

Quels sont les mots reconnus par cet automate ?

TP 26

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut

TP 27

Universit
Galatasaray

championnat de football

Prsentation
Le but de ce TP est dapprofondir des notions dj vues lors des TP prcdents : types
structurs, types numrs, passage par adresse. On veut reprsenter le championnat de
football turc de premire division (appel Sper Lig) en utilisant des types personnaliss.

1 quipes
On veut tout dabord reprsenter les quipes de Sper Lig, dont voici la liste complte :
Code
akh
ant
bes
bur
riz
ela
esk
fen
gal
gaz
ank
kar
kas
erc
kay
kon
siv
tra

Nom court
Akhisar
Antalyaspor
Beikta
Bursaspor
Rizespor
Elazspor
Eskiehirspor
Fenerbahe
Galatasaray
Gaziantepspor
Genlerbirlii
Karabkspor
Kasmpaa
Erciyesspor
Kayserispor
Konyaspor
Sivasspor
Trabzonspor

Ville
Akhisar
Antalya
stanbul
Bursa
Rize
Elaz
Eskiehir
stanbul
stanbul
Gaziantep
Ankara
Karabk
stanbul
Kayseri
Kayseri
Konya
Sivas
Trabzon

Nom complet
Akhisar Belediye Genlik ve Spor Kulb
Medical Park Antalyaspor Kulb
Beikta Jimnastik Kulb
Bursaspor Kulb Dernei
aykur Rizespor Kulb
Sanica Boru Elazspor Kulb
Eskiehirspor Kulb
Fenerbahe Spor Kulb
Galatasaray Spor Kulb
Gaziantep Spor Kulb
Genlerbirlii Spor Kulb
Kardemir Demir elik Karabkspor
Kasmpaa Spor Kulb
Kayseri Erciyes Spor Kulb
Kayserispor
Torku Konyaspor Kulb
Sivasspor Kulb
Trabzonspor A..

Exercice 1
Dfinissez un type numr t_code permettant de reprsenter les noms des quipes, en
utilisant le code unique associ chacune delle dans la table ci-dessus.

Exercice 2
Dfinissez un type structure t_equipe permettant de stocker, pour chaque quipe : son
code (code), son nom court (nom) et sa ville (ville). Le code est de type t_code, tandis
que les autres champs sont de type chane de caractre.

Exercice 3
Dclarez de faon globale un tableau equipes de type t_equipe, permettant de stocker
les donnes dcrivant toutes les quipes de Sper Lig. Vous devez initialiser ce tableau lors de
sa dclaration, en utilisant les donnes contenues dans la table ci-dessus.

TP 27

Algorithmique et programmation

1/4

championnat de football

Exercice 4
crivez une fonction void affiche_nom(t_code code) qui reoit le code dune
quipe, et affiche le nom associ ce code. Bien entendu, il faut utiliser le code en tant
quindex dans le tableau equipes.

2 Rencontres
Exercice 5
On veut maintenant reprsenter le rsultat des rencontres entre les diffrentes quipes.
Dfinissez un type structure t_rencontre qui possde les champs suivant : code de lquipe
jouant domicile (code_local), code de lquipe qui est reue (code_visiteur), nombre
de buts marqus par la premire (buts_local) et par la seconde (buts_visiteur).

Exercice 6
crivez une fonction void affiche_rencontre(t_rencontre rencontre) qui
affiche le rsultat de la rencontre reue en paramtre, exactement comme dans lexemple cidessous.
exemple : affichage de la rencontre lissue de laquelle Antalya a battu Ganziantep 2-1
Antalyaspor 2 1 Ganziantepspor

Exercice 7
crivez une fonction void initialise_score(t_rencontre* rencontre) qui
initialise alatoirement le score de la rencontre passe en paramtre. Attention : les codes des
quipes sont dj initialiss, ici on ne soccupe que du score.
Remarque : pour tirer un entier au hasard entre et , utilisez le code source suivant (qui
sera expliqu dans un TP ultrieur). Vous avez besoin dinclure la bibliothque time.h.
Placez la ligne suivante au tout dbut de votre fonction main :
srand(time(NULL));

Utilisez linstruction suivante chaque fois que vous avez besoin de tirer une
valeur n au hasard :

int n = rand()%6;

3 Championnat
On veut maintenant reprsenter toutes les rencontres du championnat. On va pour cela
utiliser une matrice de type t_rencontre et de dimension
, o N est une constante
dont la valeur correspond au nombre dquipes. Llment de cette matrice situ sur la ligne
et la colonne correspond la rencontre lors de laquelle lquipe a reu lquipe (o et
sont interprts comme les valeurs numriques des codes de ces quipes).
Remarque : bien entendu, la diagonale de cette matrice ne sera pas utilise, puisquune
quipe ne peut pas jouer contre elle-mme.

Exercice 8
fonction
void
initialise_championnat(t_rencontre
championnat[N][N]) qui reoit une matrice reprsentant un championnat, et qui initialise
alatoirement toutes les rencontres de ce championnat (en utilisant initialise_score).
crivez

une

Exercice 9
fonction
void
affiche_championnat(t_rencontre
championnat[N][N]) qui reoit une matrice reprsentant un championnat (dj initialis),
et qui affiche tous ces rsultats de faon compacte, comme dans lexemple ci-dessous.
crivez

TP 27

une

Algorithmique et programmation

2/4

championnat de football

exemple :
Akhisar
Antalyaspor
Besiktas
Bursaspor
Rizespor
...

Akhisar
1-3
2-1
1-0
5-0

Antalyaspor
1-0
1-3
2-0
0-5

Besiktas
0-2
0-4
2-1
5-0

Bursaspor Rizespor
0-1
1-2
0-0
1-1
1-1
0-0
1-2
4-4
0-5
5-0

...
...
...
...
...
...

4 Classement
Exercice 10
Pour finir, on veut savoir quelle quipe a gagn le championnat. On se propose de donner
points en cas de victoire, point en cas dgalit, et points en cas de dfaite. On utilise un
tableau dentiers de taille N pour reprsenter les points marqus par chaque quipe.
crivez une fonction void raffraichis_points(int points[N], t_rencontre
rencontre) qui met jour les points contenus dans le tableau points, en fonction du
rsultat de la rencontre rencontre passe en paramtre. Vous devez appliquer la rgle
indique ci-dessus.

Exercice 11
En cas dgalit de points entre plusieurs quipes la fin du championnat, on avantage
celle qui a la meilleure diffrence de buts. On a donc besoin de savoir le nombre de buts
marqus et encaisss par chaque quipe. L encore, on les reprsentera avec des tableaux
dentiers de taille N.
crivez une fonction void raffraichis_buts(int pour[N], int contre[N],
t_rencontre rencontre) qui met jour les buts marqus (tableau pour) et encaisss
(tableau contre) lors de la rencontre rencontre passe en paramtre.

Exercice 12
crivez une fonction void calcule_resultats(int points[N], int pour[N],
int contre[N], t_rencontre championnat[N][N]) qui calcule les points, but
marqus et buts encaisss pour toutes les rencontres du championnat pass en paramtre. Les
rsultats de ces calculs sont stocks dans les 3 tableaux passs en paramtres (points, pour,
contre).
Remarque : pensez initialiser les trois tableaux, avant de commencer les calculs.

Exercice 13
crivez une fonction int compare_equipes(t_code eq1, t_code eq2, int
points[N], int pour[N], int contre[N]) qui compare deux quipes eq1 et eq2 en
utilisant leurs rsultats passs en paramtres. La fonction doit renvoyer une valeur ngative si
eq1 est classe avant eq2, la valeur zro si les deux quipes ont le mme classement, et une
valeur positive si eq1 est classe aprs eq2.
Pour dterminer le classement relatif de deux quipes, on utilise les critres prcdemment
dfinis. Par ordre dcroissant de priorit, ces critres sont :
Plus grande nombre de points marqus ;
Plus grande diffrence de buts ;
Plus grand nombre de buts marqus.

Exercice 14

TP 27

Algorithmique et programmation

3/4

championnat de football

On reprsente le classement final du championnat laide dun tableau de type t_code et


de taille N : le premier lment contient le code de lquipe championne, le deuxime contient
celui de lquipe vice-championne, etc.
crivez une fonction void ordonne_equipes(int points[N], int pour[N],
int contre[N], t_code classement[N]) qui calcule ce classement final. Votre
fonction doit utiliser la fonction compare_equipes pour dterminer la position relative de
deux quipes.
Utilisez lalgorithme suivant (pas trs efficace, mais simple implmenter) :
On place des valeurs ngatives dans toutes les cases du tableau classement.
Puis, pour chaque quipe :
o On compare lquipe toutes les autres quipes du championnat, en
comptant le nombre dquipes qui sont classes avant : la position de
dans classement correspond alors cette valeur .
o Si classement[k] est une valeur ngative, alors on place le code de
dans cette case du tableau.
o Sinon, cela veut dire quil y a une galit : une autre quipe est dj classe
en position . On doit alors placer le code
dans la prochaine case
contenant une valeur ngative. Attention : cette case nest pas forcment la
, car il est possible que la situation dgalit concerne plus de
quipes.

Exercice 15
Enfin, crivez une fonction void affiche_classement(int points[N], int
pour[N], int contre[N], t_code classement[N]) qui affiche lcran le rsultat
du championnat, exactement comme indiqu dans lexemple ci-dessous : classement, points,
buts marqus, but encaisss, diffrence de buts.
exemple : classement purement alatoire !
Equipe
1.Antalyaspor
2.Rizespor
3.Kayserispor
4.Bursaspor
5.Elazigspor
6.Kasimpasa
7.Akhisar
8.Fenerbahce
9.Gaziantepspor
10.Galatasaray
11.Besiktas
12.Trabzonspor
13.Erciyesspor
14.Sivasspor
15.Eskisehirspor
16.Genclerbirligi
17.Konyaspor
18.Karabukspor

TP 27

Points
60
57
57
57
53
52
51
50
50
50
48
47
45
43
42
41
38
26

Pour
80
95
75
96
73
88
89
87
87
86
84
72
87
69
76
66
79
57

Contre
61
76
65
87
60
73
86
68
80
86
90
87
98
83
87
85
87
87

Difference
19
19
10
9
13
15
3
19
7
0
-6
-15
-11
-14
-11
-19
-8
-30

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 28

floutage dune image

Prsentation
Le but de ce TP est dappliquer un traitement permettant de rendre une image floue. La
manipulation de limage se fera grce la SDL, donc votre projet doit tre configur de
manire pouvoir utiliser cette bibliothque. Les fonctions que vous crirez devront
constituer une nouvelle bibliothque appele floutage.

1 Principe
On veut effectuer un traitement sur une image afin de la rendre floue. Ce type de
traitement peut tre utilis, par exemple, pour attnuer le bruit prsent dans une photo.
Lapproche la plus simple consiste remplacer, pour chaque pixel, les trois composantes de
sa couleur (rouge, vert, bleu) par une somme pondre des composantes des pixels prsents
dans son voisinage.
Nous allons reprsenter cette somme sous la forme dune matrice carre de dimensions
, o est impair, appele matrice de convolution. Llment central reprsente le pixel
que lon veut flouter. Considrons par exemple une matrice
, cet lment occupe alors la
position
et on a :
[

Chaque lment
de la matrice correspond un nombre rel, utilis comme un poids
dans la somme pondre mentionne ci-dessus. Ces valeurs doivent tre normalises, de
manire avoir
.
Soit
la composante rouge originale du pixel correspondant la position ( ) dans la
matrice. Soit la nouvelle valeur de cette composante aprs le floutage, pour le pixel central.
Notez que si les composantes sont codes sur bits, alors toutes ces valeurs sont des entiers
compris entre et
. On obtient avec le calcul suivant, et le mme principe sapplique
aux deux autres composantes (vert et bleu) :

exemple : dans lexemple ci-dessous, la figure de gauche reprsente une partie dune
image, chaque carr correspondant un pixel. On veut traiter le pixel encadr en pointills. La
zone encadre en traits pleins reprsente le voisinage du pixel pour
.
Dans la figure du milieu, on a les composantes des couleurs de chaque pixel de ce
pour tous les
voisinage. Pour la matrice , on a choisi le cas le plus simple, o
lments. La figure de droite reprsente les composantes des couleurs obtenues aprs avoir
appliqu . La couleur finale du pixel flout est obtenue en calculant faisant la somme, pour
chaque composante, des valeurs pondres.

TP 28

Algorithmique et programmation

1/4

)(

)(

)(

)(

Couleur du pixel flout : (

2 Implmentation basique
Exercice 1
Crez une bibliothque floutage qui utilise graphisme.h. Crez un fichier main.c
qui utilise floutage. Les fonctions de ce TP seront dfinir dans la bibliothque floutage.

Exercice 2
Dans notre implmentation, on veut faire varier la taille du voisinage. Pour cette raison,
les diffrentes matrices manipules (telles que ) ne peuvent pas tre passes sous la forme
classique dun paramtre m[N][N] (puisquon aurait besoin de connatre la taille). Nous
allons donc utiliser la place des pointeurs *m, qui pointeront sur des tableaux deux
dimensions. Comme nous lavons vu en cours, laccs llment
se fera donc grce
lexpression *(m+n*i+j).
Dans
floutage,
crivez
une
fonction
void
initialise_matrice_
uniforme(float *c, int n) qui reoit une matrice c de taille
et linitialise de
faon uniforme. Autrement dit, chaque lment de la matrice doit avoir la mme valeur, et
leur somme doit slever . Donc, linitialisation doit utiliser la valeur .
Remarque : attention aux conversions implicites !
exemple : pour n=3, la matrice obtenue doit tre
0.111111 0.111111 0.111111
0.111111 0.111111 0.111111
0.111111 0.111111 0.111111

Exercice 3
Dans floutage, crivez une fonction void calcule_voisinage(SDL_Surface*
image, int x, int y, Uint32* voisinage, int n) qui calcule le voisinage du

) dans limage passe en paramtre. Les couleurs des pixels du


pixel de coordonnes (
voisinage sont renvoys travers la matrice voisinage de taille
. Cette matrice sera
manipule comme expliqu ci-dessus.
Testez votre fonction sur le pixel central de limage contenue dans lalbum fourni avec ce
sujet.
exemple : pour le pixel central et n=3, vous devez obtenir le voisinage suivant (chaque
valeur reprsentant la couleur dun pixel du voisinage, sous forme de Uint32) :
14594165 14528372 14068078
14659701 14791801 13739370
13870442 14659958 14265199

TP 28

Algorithmique et programmation

2/4

Rappel : les dimensions dune variable de type SDL_Surface (exprimes en pixels)


peuvent tre obtenues grces aux champs w (largeur) et h (hauteur).

Exercice 4
Dans floutage, crivez une fonction Uint32 calcule_couleur(SDL_Surface*
image, int x, int y, float *c, int n). Elle reoit une image et doit calculer la
) dans le but de flouter limage. Cette nouvelle
nouvelle couleur du pixel de coordonnes (
couleur sera obtenue en calculant la somme pondre dcrite dans la premire section de ce
sujet. La couleur obtenue sera ensuite renvoye par la fonction sous la forme dune valeur de
type Uint32. Le paramtre c correspond la matrice , de taille
, utiliser lors du
calcul de la couleur.
Remarque : votre fonction doit utiliser calcule_voisinage.
Testez votre fonction en utilisant une matrice
dont tous les lments valent ,
comme dans lexemple de la premire section de ce sujet. Initialisez votre matrice de
convolution avec la fonction initialise_matrice_uniforme. Comme lexercice
prcdent, traitez le pixel central de limage.
exemple : pour le pixel central, vous devez obtenir la valeur 4
.

Exercice 5
Dans
floutage,
crivez
une
fonction
SDL_Surface*
floute_rectangle(SDL_Surface* source, int x, int y, int l, int h,
float *c, int n). Elle reoit une image originale source, et doit flouter ses pixels situs
), de largeur l et de
dans la zone dlimite par le rectangle dangle suprieur gauche (
hauteur h pixels. Les nouveaux pixels doivent tre dessins dans une nouvelle image, dont
ladresse est le rsultat de la fonction. La matrice de convolution est reprsente par le
paramtre c, et sa taille est n, comme pour la fonction prcdente. Votre fonction doit utiliser
calcule_couleur.
Remarque : avant de commencer flouter, vous devez faire une copie de limage
source. Vous ne devez pas modifier limage source, seulement limage cible.
Testez votre fonction sur le rectangle correspondant x=50, y=50, l=50, et h=50.
Affichez limage originale gauche de lcran, et limage floute droite. Utilisez un
voisinage de taille n=7.
exemple : limage de gauche est limage originale, celle de droite est le rsultat du
floutage pour les paramtres indiqus ci-dessus.

TP 28

Algorithmique et programmation

3/4

3 Gestion des bords


Les valeurs des paramtres utiliss jusquici ont masqu un problme qui se pose quand
un pixel se trouve trop prs du bord de limage : son voisinage nest pas compltement dfini.
Dans ce cas-l, une mthode simple consiste dupliquer les parties existantes du voisinage
pour le complter artificiellement. On peut procder par symtrie axiale, de la manire
suivante :

Dans lexemple ci-dessus, on utilise les pixels de la partie gauche du voisinage pour
remplacer les pixels manquants dans la partie droite. Si jamais le pixel concern se trouve
dans un coin de limage, il suffit de procder par symtrie centrale.

Exercice 6
Dans floutage, crivez une fonction void calcule_voisinage2(SDL_Surface*
image, int x, int y, Uint32* voisinage, int n) qui calcule le voisinage du
) dans limage passe en paramtre. Il sagit dune version
pixel de coordonnes (
amliore de calcule_voisinage, qui est capable de traiter de complter le voisinage du
pixel si celui-ci est incomplet.

Exercice 7
Modifiez la fonction calcule_couleur, de manire ce que celle-ci utilise
calcule_voisinage2 au lieu de calcule_voisinage. crivez une fonction
SDL_Surface* floute_image(SDL_Surface* source, float *c, int n) qui
utilise floute_rectangle pour flouter lintgralit dune image.
Testez votre fonction sur la mme image, avec diffrentes tailles de voisinage (pensez
utiliser des valeurs impaires !).
exemples : images obtenues pour n=0, 3, 7, 11, 19 :

Remarque : vous noterez que le temps de calcul augmente rapidement avec .

TP 28

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 29

flous avancs

Prsentation
Ce TP est la suite de celui portant sur le floutage dune image. Il est ncessaire davoir
dabord effectu ce TP-l avant de faire ce TP-ci. Certaines des fonctions dveloppes lors du
TP prcdent sont fournies avec ce sujet, sous la forme de la bibliothque floutage.h, qui
sera complte au cours du prsent TP.

1 Flou gaussien
La mthode de floutage tudie lors du TP prcdent reposait sur lutilisation dune
matrice de convolution uniforme, i.e. contenant des poids tous gaux. Mais on peut aussi
utiliser des poids diffrents. Le flou gaussien repose ainsi sur lide que le poids des pixels
proches du pixel considr doit tre plus lev que le poids des pixels loigns. Ce flou tire
son nom du fait quon se base sur la loi de Gauss pour calculer le poids dun pixel du
voisinage en fonction de sa distance au pixel considr :
(

La variable reprsente la dispersion de la loi de Gauss : plus elle est faible et plus la
distance influence le poids.
Limite du voisinage

Poids

Poids

Limite du voisinage

Distance

Distance

Poids uniformes

Poids gaussiens

On peut comparer visuellement les poids uniformes et ceux bass sur la loi de Gauss : les
graphiques ci-dessus montrent comment le poids volue en fonction de la distance entre le
pixel du voisinage et le pixel considr.

Exercice 1
Dans floutage, crivez une fonction void normalise_matrice(float *c, int
n) qui reoit une matrice de convolution et la normalise, de manire ce que la somme de ses
valeurs soit gale .
exemple : la matrice [

] devient [

].

Exercice 2

TP 29

Algorithmique et programmation

1/5

flous avancs

crivez une fonction void initialise_matrice_gaussienne(float *c, int


n, float sigma) qui initialise une matrice de convolution en utilisant la mthode dcrite
ci-dessus.
Testez votre fonction en appliquant le flou uniforme et le flou gaussien limage, avec la
mme valeur de n, et en affichant simultanment les deux images obtenues.
Remarque : dclarez des constante PI et EXP pour reprsenter
(
) et
(
).
exemple : pour n=7 et sigma=3, on obtient les valeurs suivantes :
0.011297
0.014915
0.017619
0.018626
0.017619
0.014915
0.011297

0.014915
0.019690
0.023261
0.024590
0.023261
0.019690
0.014915

0.017619
0.023261
0.027480
0.029050
0.027480
0.023261
0.017619

0.018626
0.024590
0.029050
0.030709
0.029050
0.024590
0.018626

0.017619
0.023261
0.027480
0.029050
0.027480
0.023261
0.017619

0.014915
0.019690
0.023261
0.024590
0.023261
0.019690
0.014915

0.011297
0.014915
0.017619
0.018626
0.017619
0.014915
0.011297

Exercice 3
Depuis la fonction main, exprimentez en appliquant le flou gaussien avec un voisinage
assez grand et diffrentes valeurs de .
exemples :
et
; ; ; et :

Appliquez aussi les deux types de flou limage, en utilisant les paramtres
. Notez que le flou obtenu avec la mthode gaussienne ( droite) est plus liss :

et

2 Flou cintique
Le flou cintique consiste crer un effet ressemblant celui obtenu quand un objet en
dplacement est pris en photo. Cet effet peut tre produit en utilisant une matrice de
convolution contenant simplement une ligne. Par exemple, la matrice suivante produit un flou
simulant un dplacement diagonal :

TP 29

Algorithmique et programmation

2/5

flous avancs

Exercice 4
Toujours dans la bibliothque floutage, crivez une fonction void initialise_
matrice_cinetique(float *c, int n, float coef_dir, int multiplicite)

qui initialise une matrice de convolution avec des valeurs permettant dobtenir un flou
cintique.
Le paramtre coef_dir contrle le coefficient directeur de la droite principale.
exemples : matrices obtenues pour multiplicite=1 et coef_dir=0.5, 1 et 2 :
0.0
0.2
0.0
0.0
0.0

0.0
0.0
0.2
0.0
0.0

0.0
0.0
0.2
0.0
0.0

0.0
0.0
0.2
0.0
0.0

0.0
0.0
0.0
0.2
0.0

0.2
0.0
0.0
0.0
0.0

0.0
0.2
0.0
0.0
0.0

0.0
0.0
0.2
0.0
0.0

0.0
0.0
0.0
0.2
0.0

0.0
0.0
0.0
0.0
0.2

0.0
0.0
0.0
0.0
0.0

0.2
0.0
0.0
0.0
0.0

0.0
0.2
0.2
0.2
0.0

0.0
0.0
0.0
0.0
0.2

0.0
0.0
0.0
0.0
0.0

Remarque : noubliez pas quavec la SDL, laxe des ordonnes est invers par rapport
la convention utilise en mathmatiques. De plus, pensez distinguer les deux cas suivants :
Coefficient directeur plutt vertical (i.e. de valeur absolue suprieure ) ;
Coefficient directeur plutt horizontal (i.e. de valeur absolue comprise entre et
).
Le paramtre multiplicite indique si on veut ddoubler la droite principale, avec des
droites parallles de poids infrieur. Le fait de ddoubler les droites permet de lisser plus ou
moins le floutage. On procde de la faon suivante :
La droite principale (reprsente en bleu dans lexemple) a un poids de valeur
multiplicite ;
Les droites qui sont juste au-dessus et juste au-dessous (en orange) ont poids de
valeur multiplicite-1 ;
Les droites qui sont au-dessus/dessous de celles-ci (en vert) ont un poids de valeur
multiplicite-2 ;
Etc.
Une fois que les poids ont t calculs sous forme de valeurs entires comme expliqu cidessus, il suffit de normaliser la matrice pour respecter la contrainte qui veut que la somme
des poids est . On obtient alors des valeurs de la forme de celles donnes en exemple cidessous.
exemples : matrices obtenues pour coef_dir=0.5 et multiplicite=1, 2 et 3 :
0.00
0.20
0.00
0.00
0.00

0.00
0.00
0.20
0.00
0.00

0.00
0.00
0.20
0.00
0.00

0.00
0.00
0.20
0.00
0.00

0.00
0.00
0.00
0.20
0.00

0.05
0.10
0.05
0.00
0.00

0.00
0.05
0.10
0.05
0.00

0.00
0.05
0.10
0.05
0.00

0.00
0.05
0.10
0.05
0.00

0.00
0.00
0.05
0.10
0.05

0.05
0.07
0.05
0.02
0.00

0.02
0.05
0.07
0.05
0.02

0.02
0.05
0.07
0.05
0.02

0.02
0.05
0.07
0.05
0.02

0.00
0.02
0.05
0.07
0.05

Exercice 5
Dans la fonction main, appliquez le flou cintique en exprimentant avec les valeurs des
paramtres, en particulier le coefficient directeur.
exemples : images obtenues avec des coefficient directeurs de 0, 0.5, 1, 2 et 1000 :

TP 29

Algorithmique et programmation

3/5

flous avancs

3 Flou radial
Le flou radial consiste effectuer un flou cintique, mais en utilisant une matrice de
convolution diffrente pour chaque pixel. On va dabord slectionner un pixel dans limage
qui servira de point de fuite. Puis, le coefficient directeur utilis pour gnrer la matrice de
convolution dun pixel donn correspondra celui de la droite passant par le point de fuite et
le pixel concern. Dans lexemple ci-dessous, il sagit de la droite reprsente en rouge.
Point de fuite

Pixel considr

Exercice 6
floutage, crivez une fonction float
calcule_coefficient_
directeur(int x1, int y1, int x2, int y2) qui calcule le coefficient directeur de

Dans

) et (
). En dehors du cas gnral, deux cas particuliers
la droite reliant les points (
sont considrer :
Le cas o la droite est verticale (i.e.
) : on renvoie alors la valeur maximale
que le type float peut reprsenter.
Le cas o les deux points sont confondus (i.e.
et
) : on renvoie
alors la valeur .
Remarque : la bibliothque float.h contient la constante FLT_MAX, correspondant la
valeur maximale quon peut reprsenter avec un float.
exemples :
) et (
):
Points (
(cas gnral) ;
) et (
) : FLT_MAX (droite verticale) ;
Points (
) et (
) : (mme point) ;
Points (
(
)
(
) : (droite horizontale).
Points
et

Exercice 7

TP 29

Algorithmique et programmation

4/5

flous avancs

crivez une fonction SDL_Surface* floute_image_radial(SDL_Surface*


source, int x, int y) qui applique un flou radial limage passe en paramtre, en
).
prenant comme point de fuite le pixel de coordonnes (
Remarque : lors de la gnration des matrices de convolution, fixez les paramtres
multiplicite=1 et n=11.
Testez dabord votre fonction en utilisant comme point de fuite le pixel situ entre les
). Exprimentez ensuite avec dautres
deux yeux de Mon Lisa, de coordonnes (
points de fuite.
exemples : gauche, le point de fuite est celui indiqu ci-dessus ; droite cest le centre
de limage.

TP 29

Algorithmique et programmation

5/5

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 30

gestion dun lexique

Prsentation
Dans ce TP, on veut implmenter un certain
nombre de fonctions permettant daccder un
lexique contenant uniquement des mots de
lettres. Vous aurez pour cela besoin du contenu
de larchive fournie avec ce sujet. Certains
correspondent la bibliothque chaine, qui
permet de manipuler de chanes de caractres, et
qui a t crite lors dun TP prcdent. Dautres
correspondent une nouvelle bibliothque
lexique, que les exercices de ce TP vont
permettre de complter.

1 Dfinition du lexique
Le fichier lexique.c contient une variable globale lexique dsignant un tableau de
pointeurs sur des chanes de caractres. Chacune de ces chanes est un mot de lettres. Le
tableau contient TAILLE_ LEXIQUE mots (il y a des rptitions : certains mots sont contenus
plusieurs fois). Les mots ne sont pas rangs dans lordre lexicographique.

Exercice 1
Donnez le type et la valeur des expressions suivantes :

*lexique
lexique+1
*(lexique+2)

*(lexique+1)+1
*(*(lexique+2)+2)
*(*(lexique+3)+5)

Exercice 2
crivez une fonction affiche_lexique qui affiche lintgralit du lexique, en
numrotant chaque mot, de la faon suivante :
lexique[0]="drap"
lexique[1]="nuee"
lexique[2]="agit"
lexique[3]="mais"
lexique[4]="krak"
...

Vous devez respecter exactement cet affichage, y compris les guillemets "". Cette
fonction et toutes les suivantes doivent tre places dans la bibliothque lexique et testes
dans le main.

2 Recherche dans le lexique


Exercice 3

TP 30

Algorithmique et programmation

1/3

gestion dun lexique

En utilisant les fonctions de la bibliothque chaine, crivez une fonction int


cherche_prefixe(char *prefixe) capable de parcourir le lexique et dafficher tous les
mots qui sont prfixs par prefixe. La fonction renvoie un entier correspondant au nombre
total de mots prfixs.
exemple : cherche_prefixe("tr") doit afficher exactement les lignes suivantes (y
compris les guillemets "" et lalignement des numros de ligne) :
la chaine "tr" est un prefixe des mots suivants :
1.lexique[162]="trie"
2.lexique[164]="tram"
3.lexique[170]="trac"
4.lexique[174]="tria"
5.lexique[178]="trio"
6.lexique[181]="troc"
7.lexique[184]="trot"
8.lexique[187]="trop"
9.lexique[188]="trou"
10.lexique[197]="truc"
11.lexique[366]="tres"
La chaine "tr" est prefixe de 11 mots du lexique

Remarque : lors du test de votre fonction cherche_prefixe, laffiche de la dernire


ligne de lexemple ci-dessus doit tre ralis dans la fonction main.

Exercice 4
crivez une fonction int cherche_premier() renvoyant la position dans lexique (i.e.
lindex) du plus petit mot. Autrement dit : le premier mot du lexique dans lordre
lexicographique.
exemple : la fonction doit renvoyer lindex
, qui correspond au mot
lexique[6]="aaai".

Exercice 5
crivez une fonction int cherche_premier_partiel(int debut), qui cherche
elle aussi le mot le plus petit, mais seulement dans la partie du lexique comprise entre debut
et TAILLE_LEXIQUE (et non plus dans le lexique complet).
exemple : lappel chercher_premier_partiel(7) doit renvoyer lindex
, qui
correspond au mot lexique[930]="abat".

3 Tri du lexique
Exercice 6
crivez la fonction void permute_mots(int i, int j) capable dchanger deux
mots du lexique dsigns par leurs positions i et j dans lexique. Lchange doit tre ralis
sans recopier aucune chane de caractres, simplement en manipulant les pointeurs.

Exercice 7
crivez une fonction trie_lexique qui trie le lexique par ordre lexicographique en
appliquant lalgorithme dcrit ci-dessous.
un moment donn de lexcution, on considre quil y a deux parties dans le lexique :
La partie situe avant une position p, qui a dj t trie ;
La partie situe sur et aprs cette position p, qui contient les mots pas encore tris.
Au dbut de lalgorithme, cette position p est , car aucun mot na encore t tri. la fin
de lalgorithme, la position p est TAILLE_ LEXIQUE, car tous les mots ont t tris. Le
schma ci-aprs illustre cette volution : la partie bleue est la partie trie, la partie rouge est la
partie pas encore trie.

TP 30

Algorithmique et programmation

2/3

gestion dun lexique

T-3 T-2 T-1

Initialisation
p
Itration 1
p
Itration 2
p

Itration T-1
p
Itration T
p

Lalgorithme lui-mme est le suivant :


On rpte :
o On dtermine la position du plus petit mot m1 du lexique (daprs lordre
lexicographique) qui na pas encore t trait ;
o On change sa position avec le premier mot m2 ne pas avoir t dj
trait. Attention, ici premier signifie : dindice minimum, donc le mot
occupant la position p ;
o On considre que m1 a t trait (i.e. il est sa position dfinitive dans le
lexique tri) en incrmentant la position p.
Jusqu ce quon ait trait tous les mots du lexique.
exemple : en affichant le lexique aprs lavoir tri, on doit obtenir le rsultat suivant :
lexique[0]="aaai"
lexique[1]="abat"
lexique[2]="abbe"
lexique[3]="abri"
...

TP 30

Algorithmique et programmation

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 31

allocation dynamique

Prsentation
Le but de ce TP est dtudier comment la mmoire est organise, et de manipuler les
diffrentes fonctions standard permettant dallouer/librer la mmoire de faon dynamique.
Une bibliothque util est fournie pour lun des exercices portant sur les chanes de
caractres (elle est ncessaire seulement si vous travaillez sour Linux, pas Windows).

1 Organisation de la mmoire
On reprend lexercice du TP sur les variables, qui consistait crer des variables locales et
globales et afficher leurs adresses afin de dterminer comment la mmoire est organise
pour un programme C.
Le rsultat de lexcution indiquait que les variables globales taient cres en partant
dune certaine adresse, en incrmentant ladresse pour chaque nouvelle variable cre, tandis
que les variables locales taient cres en partant dune adresse infrieure, et en dcrmentant
ladresse pour chaque nouvelle variable cre. Pour plus de dtails, cf. le corrig de ce TP.

Exercice 1
Copiez-collez le code source partir de la correction du TP mentionn ci-dessus. Puis,
adaptez-le pour tudier lallocation dynamique :
Dans la fonction main, dclarez pointeurs sur des valeurs short nots m, n, o, s,
t, et u.
Avant lappel fonction, allouez dynamiquement une zone mmoire de taille
short pour m, n et o. Affichez ensuite les adresses de ces zones mmoire.
Dans la fonction, dclarez
pointeurs short* : p, q et r, et allouez-leur
dynamiquement une zone mmoire de taille short. Affichez les adresses de ces
zones mmoire.
Dans la fonction main, aprs lappel fonction, allouez dynamiquement une
zone mmoire de taille short pour s, t et u. Affichez les adresses de ces zones
mmoire.
Attention : vous devez garder laffichage des adresses des variables locales et globales
existantes.
Indiquez vos rsultats et commentez-les. Que pouvez-vous en dduire sur la localisation
du tas dans la mmoire ?

2 Tableaux dentiers
Exercice 2
crivez une fonction alloue_tableau1 qui cre un tableau de type short et qui
linitialise en affectant la valeur chaque lment. La taille du tableau (nombre dlments)
et passe la fonction sous la forme dun paramtre taille. La zone de mmoire
correspondant au tableau doit tre alloue dynamiquement. Ladresse de cette zone est

TP 31

Algorithmique et programmation

1/3

allocation dynamique

renvoye par la fonction grce linstruction return. La fonction doit renvoyer NULL en cas
derreur lors de lallocation. Testez votre fonction depuis la fonction main, en affichant le
contenu du tableau cr.
Remarque : pour laffichage du tableau, vous pouvez dfinir une fonction void
affiche_tableau(int *tab, int taille), car elle sera rutilise plus loin.

Exercice 3
crivez une fonction alloue_tableau2 qui ralise la mme tche, mais cette fois
ladresse de la zone doit tre passe via un paramtre de la fonction appel tab. L encore,
testez votre fonction dans la fonction main en affichant le tableau obtenu.

3 Chanes de caractres
Remarque : vous devez programmer toutes les manipulations de chanes de caractres, et
donc vous navez pas droit aux fonctions de string.h.

Exercice 4
crivez une fonction saisis_chaine_tampon qui saisit une chaine de caractres en
utilisant un tampon. Lespace mmoire permettant de stocker la chane de caractres doit tre
allou dynamiquement, et son adresse renvoye via un paramtre.
Lalgorithme est le suivant :
1) Un tableau de caractres temp, est cr de faon statique, localement la fonction.
On lappelle le tampon (ou buffer en anglais).
2) La chane est saisie par lutilisateur grce scanf ou gets, et est place dans le
tableau temp.
3) La longueur de la chaine est calcule.
4) Une zone mmoire de la taille adquate est alloue dynamiquement.
5) Le contenu du tableau est copi dans cette zone de mmoire.
6) Ladresse de la zone mmoire est renvoye via le paramtre.

Exercice 5
crivez une fonction saisis_chaine_direct qui effectue la mme opration que
saisit_chaine_tampon, mais cette fois sans utiliser de tampon (i.e. sans le tableau de
caractres temp local la fonction).
Pour cela, vous utiliserez la fonction getch, qui permet de saisir un caractre en mode
non-buffris. La fonction getch sutilise comme getchar, mais lutilisateur na pas besoin
de taper la touche entre la fin de la saisie. Son utilisation dpend de votre systme
dexploitation :
Sous Windows, vous devez inclure la bibliothque conio.h pour pouvoir utiliser
getch, et le caractre correspondant la touche entre est '\r'.
Sous Linux, vous devez utiliser la fonction getch dfinie dans la bibliothque
util.h donn avec le sujet, et le caractre reprsentant la touche entre est '\n'.

4 Tableaux de pointeurs
On veut manipuler un ensemble de mots. La mthode la plus simple est de les ranger dans
un tableau. Comme un mot correspond une chane de caractres (tableau de type char), on
obtient finalement, pour reprsenter notre ensemble, un tableau de tableaux de caractres
(tableau de type char deux dimensions).
Le problme est que les mots nont pas forcment la mme taille. Si on utilise des
tableaux statiques pour reprsenter les mots, on perd de la place en mmoire.

TP 31

Algorithmique et programmation

2/3

allocation dynamique

exemple : char tab[N][M] pour N=4 mots de taille M=6


tab[0]
c a s \0

pile

tab[1]

tab[2]

i n f o \0

u n \0

tab[3]
a \0

place perdue
Une solution possible consiste utiliser un tableau de pointeurs. Chaque pointeur pointe
vers un tableau de caractres allou dynamiquement (et donc : sans perte de place).
tab[3]

tab[2]

tab[1]

tab[0]

pile

tas

c a s \0 i n f o \0

u n \0 a \0

Exercice 6
Dclarez une variable globale mots pouvant contenir N pointeurs vers des chaines de
caractres. crivez ensuite une fonction void remplis_mots(), qui :
1) Utilise lune des deux fonctions prcdentes pour saisir la liste de mots et la
stocker dans mots, comme dcrit dans le schma prcdent ;
2) Afficher lensemble des mots contenu dans mots.
exemple : pour
Entrez le
Entrez le
Entrez le
Entrez le
Entrez le
Entrez le
Entrez le
Entrez le
Entrez le
Entrez le
Mot n.0 :
Mot n.1 :
Mot n.2 :
Mot n.3 :
Mot n.4 :
Mot n.5 :
Mot n.6 :
Mot n.7 :
Mot n.8 :
Mot n.9 :

TP 31

mot n.0 : arbre


mot n.1 : rododendron
mot n.2 : trompe
mot n.3 : a
mot n.4 : partie
mot n.5 : train
mot n.6 : balle
mot n.7 : chien
mot n.8 : anticonstitutionnellement
mot n.9 : desoxyribonucleique
arbre
rododendron
trompe
a
partie
train
balle
chien
anticonstitutionnellement
desoxyribonucleique

Algorithmique et programmation

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 32

gnrateur pseudo-alatoire

Prsentation
Dans ce TP, on sintresse aux mthodes permettant un ordinateur de gnrer des
nombres alatoires. Nous utiliserons des tableaux et les mthodes dallocation dynamique
vues en cours.

1 Mthode de Lehmer
Dans un grand nombre dapplications, on a besoin de
pouvoir gnrer des nombres de faon alatoire : calcul
statistique, simulation physique, jeux vido, cryptographie,
etc. Mais, par dfinition, le fonctionnement dun ordinateur
classique est dterministe : les mmes causes entranent
toujours le mme rsultat. Cela signifie quil est absolument
impossible de gnrer alatoirement un nombre avec un
ordinateur (sauf si on utilise un matriel spcifique).
Pour rsoudre ce problme, diffrentes mthodes ont t
dveloppes pour simuler le hasard, et gnrer des nombres
en essayant de reproduire le mieux possible les proprits dun tirage alatoire. Les
algorithmes qui utilisent ces mthodes sont appels des gnrateurs pseudo-alatoires de
nombres.
Un gnrateur pseudo-alatoire permet de produire une squence de nombres contenus
dans un intervalle donn, de manire ce que chaque nombre soit apparemment indpendant
du prcdent (on ne peut pas facilement prvoir quel sera le prochain nombre de la squence).
De plus, le gnrateur est dfini de manire ce que cette squence reproduise les proprits
dune distribution de probabilits donne.
La plupart des gnrateurs alatoires simulent une distribution uniforme, c'est--dire une
distribution pour laquelle toutes les valeurs de lintervalle possdent la mme probabilit
], chaque valeur
dapparition. Par exemple, pour un intervalle entier [
aura une
dtre tire au sort.
probabilit
Un gnrateur alatoire est gnralement construit partir dune suite mathmatique ( )
possdant certaines proprits. Dans ce TP, on sintresse la mthode du gnrateur
congruentiel linaire, dveloppe par Derrick Lehmer en 1948. Elle utilise la suite suivante :
(
)
La tche consistant dterminer les valeurs des paramtres , et sort du cadre de ce
TP. Nous utiliserons les valeurs
,
et
, qui fonctionnent
]. Le terme initial
relativement bien pour gnrer des valeurs dans [
est appel la
graine du gnrateur pseudo-alatoire. Pour une suite donne et des paramtres fixs, le fait
dutiliser la mme graine produira toujours la mme squence de nombres. Cette proprit
(parmi dautres) diffrencie un gnrateur pseudo-alatoire dun gnrateur alatoire.

TP 32

Algorithmique et programmation

1/4

gnrateur pseudo-alatoire

2 Implmentation
Exercice 1
Crez la bibliothque alea (i.e. crez les fichiers ncessaires, en leur donnant des noms
appropris). Dans cette bibliothque, dfinissez la fonction unsigned char
genere_nombre_lehmer() qui calcule le terme suivant dans la suite dcrite ci-dessus, et
renvoie sa valeur. Vous devez dfinir toutes les constantes/macros/variables ncessaires, en
utilisant les classes de mmorisation appropries. On supposera que la graine
vaut .
Crez un fichier main.c qui contiendra la fonction main. Dans cette fonction main,
ajoutez les instructions ncessaires pour tester genere_nombre_lehmer : effectuez
appels de la fonction et affichez les valeurs obtenues.
exemple : le test doit provoquer exactement laffichage suivant :
graine: 0
nombres: 187 206 249 252 151 138 149 120 243 198

Exercice 2
La graine est initialise de faon statique, et par consquent la fonction
genere_nombre_lehmer va produire exactement la mme squence de nombres chaque
excution. Pour viter cela, il faut initialiser la graine dynamiquement. Le plus simple est
dutiliser lheure actuelle : cette valeur sera diffrente chaque excution (car le temps
scoule), et donc la squence sera diffrente chaque excution.
La fonction time_t time(time_t* t) contenue dans la librairie standard time.h
prend en paramtre ladresse dune variable de type time_t, et lui affecte la date et lheure
actuelles exprimes en secondes. Le type time_t est aussi dfini dans time.h et permet de
reprsenter des donnes temporelles. La fonction renvoie
en cas derreur, et sinon elle
renvoie la date et lheure actuelles exprimes en secondes (i.e. la mme valeur que celle
place dans t).
Dans la bibliothque alea, crivez une fonction unsigned
char
init_graine_lehmer() qui initialise la graine en utilisant la fonction time. Votre
fonction doit aussi renvoyer la valeur de la graine par valeur. De plus, vous devez tester les
ventuels cas derreurs (et cette remarque vaut pour toutes vos fonctions en gnral).
Testez votre fonction init_graine_lehmer depuis la fonction main, en lappelant
plusieurs fois et en affichant la valeur de la graine chaque fois. Testez ensuite son effet sur
genere_nombre_lehmer : excutez plusieurs fois le test de cette fonction (dfini pour
lexercice prcdent) et vous devriez obtenir
nombres diffrents chaque nouvelle
excution.
exemple : pour excutions, le test doit provoquer un affichage du type :
graine: 211
nombres: 166 145 84 175 98 45 208 11 158 73
graine: 226
nombres: 173 80 139 30 201 76 103 218 101 200
graine: 2
nombres: 205 112 171 62 233 108 135 250 133 232

Exercice 3
On veut gnrer n nombre entiers et les placer dans un tableau de dimension approprie.
Dans alea, crivez une fonction unsigned char* genere_tableau_lehmer(int n)
qui alloue dynamiquement la mmoire ncessaire, initialise le tableau alatoirement et renvoie
son adresse. Testez cette fonction dans la fonction main et affichez le contenu du tableau
obtenu.
exemple : pour
, le test doit provoquer un affichage du type :
graine: 23

TP 32

Algorithmique et programmation

2/4

gnrateur pseudo-alatoire

nombres: [ 10 21 248 115 70 49 244 79 2 205 112 171 62 233 108 ]

3 Vrification
Exercice 4
On veut vrifier que les nombres gnrs suivent bien une distribution uniforme. Pour
cela, on peut calculer certaines statistiques, comme la moyenne , lcart-type et les valeurs
minimales
et maximales
gnres. Les valeurs attendues pour cette distribution sont
respectivement :
(
)

;
(
)

.
Dans alea, crivez une fonction calcule_stats qui calcule et renvoie ces statistiques
pour un tableau pass en paramtre. vous de dterminer les paramtres appropris, sachant
quaucun affichage ne doit tre ralis dans cette fonction.
Testez votre fonction depuis la fonction main, en affichant ces statistiques pour des
tableaux de tailles
,
,
,
et
. Que remarquez-vous ?
exemple : le test doit provoquer un affichage du type suivant (attention : vous devez
respecter cette mise en forme) :
graine: 157
n=
10: min= 56, max=192, moy=131.10, et=53.02
n=
100: min= 2, max=255, moy=117.18, et=77.46
n= 1000: min= 0, max=255, moy=127.08, et=73.64
n= 10000: min= 0, max=255, moy=127.54, et=73.92
n=100000: min= 0, max=255, moy=127.51, et=73.90

Remarque : pour calculer lcart-type, vous aurez besoin des fonctions pow(x,y) et
sqrt(x) contenues dans math.h, qui permettent respectivement de calculer
et . Pour
utiliser cette bibliothque sous Linux, il est ncessaire de configurer le linker en allant dans
les proprits du projet, puis C/C++ Build > Settings > Tool Settings > gcc C linker >
Libraries, puis dans longlet Libraries (-l) ajoutez la librairie m.

Exercice 5
Ces statistiques ne permettent toutefois pas de caractriser compltement la distribution
des valeurs gnres. Pour plus de prcision, on peut lafficher directement sous la forme dun
histogramme.
Dans alea, crivez une fonction void calcule_repartition qui reoit un tableau et
calcule la distribution des valeurs quil contient. Cette distribution doit prendre la forme dun
tableau dist de taille
, dont llment dist[i] contient le nombre doccurrences
de la valeur i. Ainsi, dist[58] contient le nombre dapparitions de la valeur
dans le
tableau gnr. Vous devez dcider des paramtres ncessaires votre fonction, sachant
quelle doit allouer dist dynamiquement et quelle ne renvoie rien par return.
Testez votre fonction depuis la fonction main en gnrant un tableau de taille
puis
en affichant le contenu de dist et en vrifiant manuellement que les occurrences
correspondent.
exemple :
nombres: [ 105 236 7 122 4 104 99 182 33 100 ]
dist:
d( 0)= 0
d( 1)= 0
d( 2)= 0
d( 3)=
d( 8)= 0
d( 9)= 0
d( 10)= 0
d( 11)=
......

TP 32

Algorithmique et programmation

0
0

d( 4)=
d( 12)=

1
0

........
........

3/4

gnrateur pseudo-alatoire

Exercice 6
Dans la fonction main, utiliser lune des deux fonctions histogramme_xxx de la
bibliothque histogramme pour obtenir une reprsentation visuelle de la distribution
obtenue avec calcule_repartition.
Testez votre fonction depuis la fonction main sur un tableau de
nombres. La
distribution vous parait-elle uniforme ?
exemple :
graine: 105
0 | ***************************************
1 | ***************************************
2 | ***************************************
3 | ***************************************
.......

TP 32

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 33

nombres hexadcimaux

Prsentation
Le but de ce TP est dapprofondir les chanes de caractres, les pointeurs et lallocation
dynamique, en reprsentant et manipulant des nombres hexadcimaux sous forme de chanes
de caractres.

1 Principe
On veut manipuler des entiers naturels exprims en base
. Un chiffre de la base
correspond soit un chiffre de la base
(0,,9), soit lune des premires lettres de
lalphabet latin ( , ).
On dcide dutiliser des valeurs de types char pour un reprsenter des chiffres de la base
16, ce qui permet de mlanger chiffres classiques et lettres. Par consquent, on utilisera des
chanes de caractres pour reprsenter des nombres de la base .
exemples :
Les chiffres ( ) et ( ) sont respectivement reprsents par '1' et 'A'.
) et (
) sont reprsents par "1234" et "1FF".
Les nombres (
Dans la suite du sujet, le mot chiffre dsigne un caractre reprsentant un chiffre de la
base , et le mot nombre dsigne une chane de caractres reprsentant un nombre exprim
en base .
Remarques :
Pensez que vous pouvez rutiliser les fonctions que vous crivez.
En langage C, il est possible dadditionner les caractres et les entiers.
Dans la table ASCII, les chiffres sont rangs de '0' '9', les lettres de 'A' 'Z'.
Dans la table ASCII, 'A' nest pas plac juste aprs '9'.

2 Oprations simples
Exercice 1
crivez une fonction int longueur_nombre(char *n) qui calcule la longueur dun
nombre n (i.e. combien de chiffres composent le nombre).

Exercice 2
crivez une fonction int verifie_nombre(char *n) qui vrifie quune chane de
caractres passe en paramtre reprsente bien un nombre. La fonction renvoie la valeur si
la chane est un nombre hexadcimal, ou sinon.
exemples :
Pour n="12A4", la fonction doit renvoyer .
Pour n="1 2A4", la fonction doit renvoyer .
Pour n="12G4", la fonction doit renvoyer .

TP 33

Algorithmique et programmation

1/2

nombres hexadcimaux

3 Comparaisons
Exercice 3
crivez une fonction int compare_chiffres(char c1, char c2) qui reoit deux
chiffres et qui effectue leur comparaison. La fonction doit renvoyer une valeur positive si
, nulle si
ou ngative si
.
exemples :
Pour c1='A' et c2='3', la fonction doit renvoyer une valeur positive.
Pour c1='6' et c2='6', la fonction doit renvoyer .
Pour c1='3' et c2='9', la fonction doit renvoyer une valeur ngative.

Exercice 4
crivez une fonction int compare_nombres(char *n1, char *n2) qui reoit deux
nombres et qui effectue leur comparaison. La fonction doit renvoyer une valeur positive si
, nulle si
ou ngative si
.
exemples :
Pour n1="12A" et n2="123", la fonction doit renvoyer une valeur positive.
Pour n1="12A" et n2="12A", la fonction doit renvoyer .
Pour n1="12A" et n2="12B", la fonction doit renvoyer une valeur ngative.

4 Conversions
Exercice 5
crivez une fonction char convertit_chiffre(int x) qui reoit une valeur
exprime en base , et qui renvoie le chiffre correspondant en base .
exemples :
Pour x=1, la fonction doit renvoyer '1'.
Pour x=11, la fonction doit renvoyer 'B'.

Exercice 6
crivez une fonction char* convertit_nombre(int x) qui reoit une valeur
exprime en base . La fonction doit crer un nombre reprsentant cette valeur en base ,
et renvoyer ladresse de cette chane de caractres. Lespace mmoire occup par la chane
doit tre allou dynamiquement.
exemple : pour
, la fonction doit renvoyer ladresse dune chane "FF".
Algorithme :
Calculer lespace que va occuper la chane
Faire lallocation dynamique
Calculer la reprsentation du nombre en base
: procdez par divisions
successives par .

5 Modifications
Exercice 7
crivez une fonction void incremente_nombre(char **n) qui permet dajouter la
valeur un nombre n. La fonction doit ventuellement agrandir la zone de mmoire alloue
la chane de caractres.

TP 33

Algorithmique et programmation

2/2

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 34

rpertoire tlphonique

Prsentation
Le but de ce TP est dapprofondir les mcanismes dallocation dynamique de la mmoire,
ainsi que les indirections multiples (pointeurs de pointeurs). Pour le dernier exercice, vous
aurez besoin de certaines fonctions de manipulation des chanes de caractres, contenues dans
la bibliothque chaine fournie avec ce sujet.

1 Numros de tlphone
On veut reprsenter et manipuler un ensemble de numros de tlphone. Pour cela, on va
utiliser des tableaux dentiers. Le problme est quon ne sait pas lavance combien de
numros de tlphone on va devoir stocker. On ne sait pas non plus la longueur des numros :
les numros de personnes habitant Istanbul sont de la forme XXX XX XX, les numros de
tlphones portables ou pour le reste de la Turquie sont de la forme 0 XXX XXX XX XX, les
numros pour la France sont de la forme 00 33 X XX XX XX XX, etc.
Il serait possible dutiliser des tableaux trs grands pour stocker tous ces numros, mais
cela pose deux problmes :
On ne peut pas tre certain que ces tableaux seront assez grands
Sils sont trop grands, on gaspille de lespace mmoire.
Pour viter cela, nous allons utiliser des pointeurs et les fonctions dallocation dynamique
de la mmoire (malloc, calloc, etc.).

Exercice 1
On veut reprsenter un numro tlphonique sous la forme dun tableau dentiers de taille
indtermine. Ce tableau ne contient que des chiffres : pas de ponctuation ou despace " ".
La fin de ce tableau est marque par une valeur spciale :
.
Crez une nouvelle bibliothque repertoire. Dans repertoire.h, dfinissez une
constante FIN qui prend la valeur entire
. Cette constante devra tre utilise dans vos
fonctions lorsque vous testerez la fin dun numro.
exemple : les numros 123 456 789 et 12 34 56 789 sont tous les deux reprsents
par le tableau {1,2,3,4,5,6,7,8,9,FIN}.
Remarque : on utilise un systme assez similaire celui des chanes de caractres. La
diffrence est que dans celles-ci, on utilise le caractre '\0' pour marquer la fin de chane.
Ici, on ne peut pas utiliser ce caractre, car sa valeur numrique est . Or, est une valeur tout
fait acceptable dans un numro de tlphone. Il nous faut une valeur qui ne peut pas
apparaitre normalement dans un numro : par exemple, une valeur ngative comme
.

Exercice 2
Dans repertoire, crivez une fonction void affiche_numero(int *) qui reoit
un tableau dentiers reprsentant un numro, et qui laffiche lcran, en tenant compte du
fait que la fin du numro est marque par la valeur FIN.

TP 34

Algorithmique et programmation

1/3

rpertoire tlphonique

exemple : pour le numro de lexemple prcdent, on obtient simplement :


123456789

Exercice 3
Dans repertoire, crivez une fonction void saisis_numero(int** numero) qui
permet lutilisateur de saisir un numro de tlphone. Cette saisie doit tre effectue
caractre par caractre, grce la fonction getch dj utilise lors du TP sur lallocation
dynamique.
La fonction doit filtrer la chane, de manire ne garder que les chiffres. Ces chiffres sont
stocks dans un tableau dentiers qui doit faire exactement la taille ncessaire. Il doit tre
rserv dynamiquement avec malloc, et ladresse de lespace mmoire rserv doit tre
renvoye via le paramtre numero.
exemple :
Entrez le numro de tlphone : 0 589 123 45 67

Notez que le texte Entrez le numro de tlphone est affich depuis la fonction
main. On obtient le tableau suivant en mmoire :
? ? ? 0 5 8 9 1 2 3 4 5 6 7

FIN

? ? ?

Remarque : Un tableau dentiers est de type int*. Ladresse dun tableau dentier est
donc de type int**, do le type du paramtre numero.

2 Contacts
Un numro de tlphone seul nest pas trs utile : encore faut-il savoir qui il appartient.
On veut donc non seulement stocker les numros, mais aussi les noms de leurs propritaires.
Pour cela, nous allons utiliser un type structure.

Exercice 4
Dans repertoire, dfinissez un type structur t_contact permettant de reprsenter
la fois un nom nom (i.e. une chane de caractres) et un numro de tlphone numero (i.e. un
tableau dentiers termin par FIN). Notez bien quon ne connait pas a priori les tailles de ces
tableaux.

Exercice 5
Dans repertoire, crivez les fonctions affiche_contact(t_contact contact)
et saisis_contact(t_contact* contact). La premire permet dafficher un contact
lcran, alors que la seconde permet de saisir un contact et de le renvoyer par adresse. Vous
devez bien entendu utiliser les fonctions existantes.
exemples :
Saisie dun contact :
Entrez le nom du contact : Can
Entre le numero de Can : 0538 458 12 34

Affichage de ce mme contact :

Can : 05384581234

Remarque :

pour

le nom, pensez vous inspirer


saisis_chaine_direct du TP sur lallocation dynamique.

de

la

fonction

3 Rpertoire
Nous allons utiliser un tableau de contacts pour reprsenter le rpertoire. Il est galement
ncessaire de savoir combien de contacts notre rpertoire contient.

TP 34

Algorithmique et programmation

2/3

rpertoire tlphonique

Exercice 6
Ces deux informations peuvent tre reprsentes ensemble, sous la forme dun type
structure. Dans repertoire, dfinissez le type t_repertoire, qui contient un tableau de
contacts appel contacts et un entier taille indiquant le nombre de contacts dans
contacts. Encore une fois, on ne connait pas a priori la taille maximale du rpertoire.

Exercice 7
repertoire, crivez la fonction void
initialise_repertoire
(t_repertoire* repertoire) qui initialise les deux champs du rpertoire pass en

Dans

paramtre, de manire obtenir un rpertoire vide.

Exercice 8
Dans repertoire, crivez la fonction ajoute_contact(t_repertoire*
repertoire, t_contact contact), qui permet dajouter un nouveau contact contact
dans un rpertoire existant repertoire.
Remarque : lorsque vous testez votre fonction, noubliez pas dinitialiser votre rpertoire
avant dy ajouter un contact.

Exercice 9
Dans repertoire, crivez la fonction affiche_repertoire(t_repertoire
repertoire) qui affiche tout le contenu dun rpertoire lcran.
exemples :
Pour un rpertoire vide :
Taille du repertoire : 0 contact.

Pour un rpertoire contenant plusieurs contacts :

Taille du repertoire : 3 contacts.


1.Can : 05384581234
2.Zeynep : 4443322
3.Cem : 0587123123456

Exercice 10
Dans repertoire, crivez la fonction t_contact* cherche_nom(t_repertoire
repertoire, char* nom) qui cherche si le rpertoire contient un contact qui sappelle
nom. Si ce contact existe, la fonction renvoie son adresse. Sinon, elle renvoie NULL.
exemples : on reprend le rpertoire de lexemple prcdent
Une recherche du nom "Cemm" doit renvoyer NULL.
Une recherche du nom "Zeynep" doit renvoyer ladresse du 2me contact.
Remarque : pour cet exercice, vous devez utiliser la bibliothque chaine.

Exercice 11
Dans repertoire, crivez la fonction supprime_contact(t_repertoire*
repertoire, t_contact* contact) qui supprime du rpertoire le contact spcifi. On
suppose que ce contact est bien prsent dans le rpertoire, et que ladresse passe en
paramtre nest pas NULL.

TP 34

Algorithmique et programmation

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut

TP 35

Universit
Galatasaray

fichiers et arguments dun programme

Prsentation
Le but de ce TP est de traiter deux nouveaux points :
Le passage darguments un programme via la ligne de commande :
Laccs aux fichiers en lecture et en criture.
Nous allons pour cela nous appuyer sur deux bibliothques crites lors de TP prcdents :
date, qui est spcialise dans la reprsentation et la manipulation des dates, et promotion,
qui permet de reprsenter un groupe dtudiants.
Remarques : pensez bien traiter les erreurs potentielles des fonctions daccs aux
fichiers.

1 Arguments dun programme


Lorsquon excute un programme depuis la ligne de commande du systme
dexploitation, il est possible de lui passer des arguments. Par exemple, dans la commande
suivante, le programme est cd tandis que lexpression /home est son argument :
cd /home

En langage C, ces arguments passs au programme sont rcuprs dans la fonction main
de la faon suivante :
int main(int argc, char *argv[])
{ ...
}

Lentier argc indique le nombre darguments qui ont t passs par la ligne de
commande, et le tableau argv contient ces diffrents arguments, sous la forme de chanes de
caractres.
Remarque : le nom du programme excut est compt dans les arguments, donc argv[0]
correspond toujours ce nom (ici : TP01.exe).

Exercice 1
Crez votre projet Eclipse, puis crez le programme principal main.c. crivez une
fonction void affiche_arguments(int argc, char *argv[]) qui affiche
simplement le nombre de arguments total reus par le programme, le nom du programme et la
valeur de tous les autres arguments reus. Cette fonction doit tre appele depuis la fonction
main.
Pour tester votre programme, vous devez lexcuter depuis un terminal systme, et non
pas depuis Eclipse. Ouvrez dabord un terminal systme, puis dplacez-vous jusquau dossier
contenant votre projet. Allez ensuite dans le dossier Debug et entrez le nom du fichier
excutable suivi par les arguments que vous voulez lui donner.
exemple : supposons que :
Le projet sappelle TP ;
Il se situe dans le dossier /home/student/eclipse/workspace ;
On veut lui passer les arguments aaa, 111, bcd et 123456.
Alors la squence de commandes entrer dans le terminal systme sera :
TP 35

Algorithmique et programmation

1/4

fichiers et arguments dun programme

cd /home/student/eclipse/workspace/TP
cd Debug
TP aaa 111 bcd 123456

Et vous devez obtenir laffichage suivant :


Nombre darguments recus : 5
Nom du programme : /home/student/eclipse/workspace/TP/TP
Argument 1 : aaa
Argument 2 : 111
Argument 3 : bcd
Argument 4 : 123456

Exercice 2
Il est galement possible de passer des arguments un programme quand on lexcute
depuis Eclipse, bien que cela soit moins pratique.
Allez dans le menu Run > Run configurations : une nouvelle fentre apparait.
Dans la liste des projets situs dans la partie gauche, cliquez sur celui que vous
voulez excuter.
Dans la partie droite, cliquez sur longlet Arguments : vous pouvez alors entrer vos
arguments dans la zone Program arguments. Ils seront transmis votre
programme chaque fois que vous lexcuterez.

Excutez votre programme partir dEclipse, en utilisant les mmes arguments que dans
lexercice prcdent. Vous devez obtenir exactement le mme affichage quavant.

2 Accs non-format un fichier


Exercice 3
Dans le programme principal main.c, crivez une fonction ecris_chaine qui demande
lutilisateur de saisir une chane de caractres et qui lcrit en mode caractre dans un fichier
donnees.txt situ dans le projet. En cas derreur, fonction doit renvoyer
; en cas de
succs, elle doit renvoyer le nombre de caractres crits. Attention, vous ne devez pas crire
le caractre de fin de chane '\0' dans le fichier.
Testez votre fonction depuis la fonction main, et vrifiez le fichier obtenu en louvrant
avec lditeur de texte dEclipse.
exemple : pour la chane "abcdef", si tout se passe bien, la fonction renvoie et le
fichier donnees.txt contient exactement et uniquement les caractres abcdef.
Remarques :
Les chemins relatifs sont exprims par rapport la racine du projet.
Votre programme va crer un fichier dans le projet, mais celui-ci napparaitra pas
automatiquement. Pour le voir, il faut rafraichir le projet : dans Projet Explorer (
gauche), faites un clic-droit sur votre projet, puis Refresh.

TP 35

Algorithmique et programmation

2/4

fichiers et arguments dun programme

Exercice 4
crivez une fonction lis_chaine qui lit le contenu du fichier texte prcdent, donc
toujours en mode caractre, et qui affiche la chane de caractres obtenue. En cas derreur, La
fonction doit renvoyer
; en cas de succs, elle doit renvoyer le nombre de caractres lus.
Attention : le fichier texte ne contient pas le '\0' final.
exemple : pour le fichier cr lexemple prcdent, la fonction doit renvoyer la valeur
et afficher :
La chaine lue est : "abcdef"

Exercice 5
crivez une fonction int copie_fichier(char *source, char *cible) qui cre une
copie du fichier source appele cible. Pour effectuer la copie, vous devez lire des lignes de
texte dans le fichier source et les crire dans le fichier cible. En cas de succs, la fonction
renvoie le nombre de lignes copies, en cas derreur elle renvoie
. Attention, ici on ne
travaille plus avec de simples caractres comme dans les exercices prcdents, mais avec des
chanes de caractres.
Depuis la fonction main, testez votre fonction sur le fichier donnees.txt en crant une
copie que vous appellerez copie.txt, elle aussi situe dans le projet Eclipse. Avant
dexcuter votre programme, rajoutez plusieurs lignes de texte dans donnees.txt laide de
lditeur dEclipse.
exemple : si le fichier donnees.txt contient le texte ci-dessous, alors elle doit renvoyer la
valeur .
Ceci est la premiere ligne.
Et ceci est la deuxieme ligne.
Et encore une autre, la troisieme ligne.
Enfin, on finira avec une 4eme ligne.

Exercice 6
On veut gnraliser le programme en utilisant le passage darguments tudi dans la
premire partie de ce TP :
Le premier argument du programme doit correspondre au fichier source ;
Le second argument doit correspondre au fichier cible.
Dans la fonction main, effectuez les tests ncessaires sur les arguments reus par le
programme, et appelez la fonction copie_fichier avec les paramtres appropris.
exemple : la commande suivante permet de crer une copie de donnees.txt appele
copie2.txt :
TP donnees.txt copie2.txt

Remarque : cette commande peut aussi bien tre excute dans le terminal systme, ou
bien configure dans Eclipse comme expliqu prcdemment.

3 Accs format un fichier


Exercice 7
Dans la bibliothque date, crivez la fonction int sauve_date(t_date d, FILE *fp)
utilisant laccs format pour crire une date d dans un fichier dj ouvert en criture, dsign
par le pointeur fp. En cas derreur la fonction renvoie
, et en cas de succs .
Contrainte : vous ne pouvez utiliser quune seule fois la fonction dcriture en accs
format. Utilisez "/" pour sparer les diffrentes composantes dune date.

Exercice 8

TP 35

Algorithmique et programmation

3/4

fichiers et arguments dun programme

Dans la bibliothque date, crivez une fonction int charge_date(t_date *d, FILE
*fp) qui ralise lopration inverse de sauve_date, c'est--dire qui lit une date dans un
fichier dj ouvert en lecture, dsign par le pointeur fp. La fonction renvoie
en cas
derreur, et en cas de succs. La date lue est passe par adresse.
Contrainte : vous ne pouvez utiliser quune seule fois la fonction de lecture en accs
format.

Exercice 9
Modifiez le fichier date.txt en ajoutant
zros aprs lanne de la premire date.
Chargez et affichez cette date. Que remarquez-vous ? Comment lexpliquez-vous ?

Exercice 10
Mme chose, mais cette fois en remplaant les "/" de la premire date par des ":".

Exercice 11
Dans la bibliothque promotion, crivez les fonctions sauve_etudiant et
charge_etudiant, permettant respectivement denregistrer et de lire un tudiant dans un
fichier.
Remarque : utilisez une tabulation '\t' pour sparer les diffrents champs dcrivant
chaque tudiant.

Exercice 12
Toujours dans la bibliothque promotion, crivez les fonctions sauve_promotion et
charge_promotion, qui effectuent les mmes actions pour une promotion. En cas
derreur, ces deux fonctions doivent renvoyer
; en cas de succs, elles doivent renvoyer le
nombre dtudiants crits ou lus.
exemple : pour la promotion gnre par initialise_promotion, la fonction doit
renvoyer la valeur .
Remarque : reprsentez chaque tudiant sur une ligne distincte.

TP 35

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 36

diaporama

Prsentation
Dans ce TP, on veut afficher une squence de photos en utilisant la SDL. La liste des
photos afficher est contenue dans un fichier texte. Le but de ce TP est dapprofondir le
passage de paramtres par adresse, les pointeurs, lallocation dynamique, et la manipulation
de chanes de caractres.
La bibliothque chaine contient quelques fonctions de manipulation des chanes de
caractres, utiles dans la deuxime partie du TP. La bibliothque graphisme est fournie pour
utiliser la SDL, cependant elle nest ncessaire que dans la dernire partie du TP. Pour vous
faciliter lcriture des fonctions, il est conseill de ne configurer le projet pour la SDL que
lorsque vous arriverez cette dernire partie.

1 Noms des images


Les noms des fichiers contenant les images afficher sont lists dans un fichier texte, luimme contenu dans le dossier album fourni avec le sujet. On veut reprsenter cette liste de
noms de fichiers sous la forme dun tableau contenant des pointeurs vers des chanes de
caractres. Chaque chane correspondra un nom de fichier.
Cependant, on ne connait pas lavance la taille de ce tableau, car on ne sait pas combien
de noms dimage la liste contient. Le tableau doit donc tre allou dynamiquement. La mme
remarque est valable pour les chanes, qui devront elles aussi tre alloues dynamiquement.

Exercice 1
crivez une fonction int lis_nom(FILE *fp, char** nom) qui reoit en paramtre
un fichier dj ouvert en lecture fp, et ladresse dun pointeur sur des caractres (i.e. ladresse
dune chane de caractres) nom. Cette fonction doit lire un seul nom dans fp, et le placer
dans nom. De plus, elle doit renvoyer la valeur si la fin du fichier a t atteinte lors de cette
lecture, ou sinon.
Voici lalgorithme utiliser :
Allouer un tableau de caractre (pour contenir le '\0' final).
Lire le contenu du fichier caractre la fois. Pour chaque caractre lu, on doit
effectuer les oprations suivantes :
o Dabord on r-alloue lespace mmoire de nom, de manire lagrandir
dun caractre ;
o Ensuite, on copie le caractre lu, lemplacement appropri dans nom.
On sarrte si lune des deux conditions suivantes est atteinte :
o On est arriv la fin du fichier : dans ce cas-l, on renvoie la valeur .
o On est arriv la fin de la chane (i.e. le caractre lu est '\n') : on renvoie
la valeur .
o Dans les deux cas, il faut aussi complter nom avec le dernier caractre
'\0'.

TP 36

Algorithmique et programmation

1/4

diaporama

Testez votre fonction partir de la fonction main, en procdant de la manire suivante :


Ouvrez le fichier image.txt, contenu dans le dossier album fourni avec le sujet ;
Appelez lis_nom en rcuprant son rsultat (lentier renvoy),
Affichez lentier renvoy et la chane obtenue,
Recommencez lappel 4 fois (pour lire tous les noms contenus dans
images.txt).
Vous devez obtenir exactement laffichage suivant :
res=1
res=1
res=1
res=0

nom=image2.bmp
nom=image9.bmp
nom=image6.bmp
nom=

Exercice 2
crivez une fonction int charge_liste(char fichier[], char*** images)
qui reoit en paramtre fichier (le nom du fichier texte contenant la liste dimages), ouvre
ce fichier texte en lecture, charge son contenu, et le place dans le tableau images de manire
obtenir un tableau de pointeurs vers des chanes de caractres, chacune correspondant au
nom dune image. Le tableau image doit tre (r-)allou dynamiquement, de manire faire
exactement la taille ncessaire. La fonction doit renvoyer un entier correspondant au nombre
de noms dimages lus. Vous devez, bien entendu, utiliser la fonction lis_nom.
Lalgorithme appliquer est le suivant :
Ouvrez (en lecture) le fichier pass en paramtre ;
Lisez chaque nom dimage contenu dans ce fichier grce lis_nom. Pour chaque
nom lu, il faut effectuer les oprations suivantes :
o R-allouer lespace mmoire de images, afin de lagrandir dune adresse ;
o Placer dans images, lemplacement appropri, ladresse de la chane de
caractre lue par lis_nom.
On sarrte quand on a atteint la fin du fichier (i.e. quand lis_nom renvoie ).
On ferme le fichier.
Dans la fonction main, testez votre fonction de la faon suivante :
Appliquez charge_liste au fichier images.txt contenu dans le dossier
album du projet, afin dinitialiser le tableau images.
Affichez le contenu du tableau images, de manire obtenir exactement
laffichage ci-dessous (position et nom de chaque image dans le fichier).
0. image2.bmp
1. image9.bmp
2. image6.bmp

2 Chemins des images


Les noms des images contenus dans le fichier texte images.txt ne comportent pas le
dossier contenant ces images (i.e. le dossier album). Il est ncessaire de complter leur
chemin avec ce dossier, afin de pouvoir charger les images ensuite.

Exercice 3
crivez une fonction void ajoute_dossier(char* images[], int n, char
dossier[]) qui reoit un tableau images contenant des pointeurs vers des noms dimages,

TP 36

Algorithmique et programmation

2/4

diaporama

la taille n de ce tableau (i.e. le nombre de pointeurs quil contient) et le nom dossier du


dossier contenant les images.
La fonction doit modifier chaque nom contenu dans images, de manire le prfixer
avec le nom du dossier. Par exemple, pour une image "image1.bmp" et un dossier
"album", on veut ajouter le prfixe "album/", de manire obtenir le chemin
"album/image1.bmp".
Remarque : comme dhabitude, pour Windows il faut remplacer '/' par '\\'.
Lalgorithme appliquer est le suivant :
On calcule la longueur (en caractres) du prfixe.
On traite sparment chaque nom contenu dans images.
On augmente (par r-allocation) lespace mmoire assign chaque nom.
On dplace les caractres prsents vers la fin de la chane.
On copie le prfixe au dbut de la chane.
Remarque : utilisez la bibliothque chaine pour calculer les longueurs.
Dans la fonction main, testez votre fonction de la faon suivante :
Appelez charge_liste comme prcdemment.
Appelez ajoute_dossier, en utilisant le dossier "album".
Affichez le contenu du tableau images, comme prcdemment. L encore, vous
devez obtenir exactement laffichage ci-dessous.
0. album\image2.bmp
1. album\image9.bmp
2. album\image6.bmp

3 Affichage des images


Dans cette partie, nous allons profiter du tableau images, qui contient les chemins de
toutes les images que lon veut afficher. Nous allons dessiner ces images lcran en utilisant
la SDL. La transition entre les images se fera automatiquement, avec un certain dlai de
quelques secondes pour avoir le temps de voir les images.
Vous devez dabord configurer votre projet pour quil utilise la SDL. Pensez galement,
dans la fonction main, initialiser la fentre graphique avec initialise_fenetre.

Exercice 4
crivez une fonction void diaporama_image(char *chemin, int delai) qui
reoit le chemin complet dune image et un dlai exprim en ms. La fonction doit afficher
limage au centre de la fentre graphique, puis attendre un certain dlai avant de se terminer.
Les diffrentes tapes de cette fonction sont :
Charger limage ;
Calculer les coordonnes daffichage ;
Effacer lcran ;
Afficher limage ;
Attendre le dlai spcifi.
Rappels :
Le type SDL_Surface possde des champs w et h permettant daccder
respectivement la largeur et la hauteur dune image.
La bibliothque graphisme contient deux constantes FENETRE_LARGEUR et
FENETRE_HAUTEUR, reprsentant les dimensions de la fentre graphique.

TP 36

Algorithmique et programmation

3/4

diaporama

Testez votre fonction dans la fonction main, en spcifiant manuellement un chemin


complet valide et un dlai de secondes.

Exercice 5
fonction void
diaporama_tout(char
fichier[],
char
dossier[], int delai), qui affiche successivement toutes les images du diaporama, en
les enchanant automatiquement, et en respectant le dlai spcifi. Le paramtre fichier est
le nom du fichier texte contenant la liste des images. Ce fichier texte, ainsi que les images
elles-mmes, sont contenus lemplacement spcifi, dossier.
crivez

une

Lalgorithme appliquer est le suivant :


On construit une chane de caractres en concatnant dossier et fichier
(spars par un '/')
On charge la liste dimages contenue dans ce fichier ;
On ajoute dossier aux noms de cette liste pour obtenir les chemins complets des
images ;
Pour chaque chemin obtenu, on charge et affiche limage.
Bien sr, il faut utiliser les fonctions des exercices prcdents.
Testez votre fonction dans la fonction main, en utilisant le dossier "album", le fichier
"images.txt" et un dlai de seconde.
Remarque : vous pouvez manuellement diter le fichier texte images.txt pour y
rajouter dautres images, et rallonger ainsi la dure du diaporama.

TP 36

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 37

stock dune librairie

Prsentation
Le but de ce TP est dapprofondir certaines notions dj vues en cours et appliques lors
dautres TP, en particulier : allocation dynamique, types structurs, et accs aux fichiers.
Larchive fournie avec ce sujet contient la bibliothque date, crite et utilise lors de TP
prcdents, et qui est ncessaire pour certaines questions.

1 Structure de donnes
On veut raliser un programme permettant de reprsenter lensemble des livres doccasion
(i.e. des livres qui ne sont pas neufs) vendus par une librairie. Chaque livre est caractris par
un code compos de caractres, et par la date laquelle il a t publi.
La librairie peut possder plusieurs exemplaires dun mme livre. Chaque exemplaire peut
avoir un prix diffrent (suivant quil est en bon tat ou en mauvais tat).

Exercice 1
Dans votre projet, crez une bibliothque livre, et dfinissez un type t_livre permettant
de reprsenter un livre par :
Son code ;
Sa date de publication ;
Le nombre dexemplaires que la librairie possde ;
Les prix du livre (chaque exemplaire peut avoir un prix diffrent).
Remarque : on ne connait pas lavance le nombre dexemplaires dun livre, et on ne
veut pas fixer de limite a priori : il faut donc utiliser un tableau allou dynamiquement.

2 Affichage & saisie


Exercice 2
Dans la bibliothque livre, crivez une fonction void affiche_livre(t_livre
livre) qui affiche les caractristiques du livre pass en paramtre.
exemple : livre de code AGZ12 publi le 12/10/2004 et prsent en exemplaires de prix
,
et
:
AGZ12 - 12 octobre 2004 - 3 exemplaires : 12.50 20.00 12.30

Exercice 3
Dans la bibliothque livre, crivez une fonction void saisis_livre(t_livre
*livre) qui permet lutilisateur de saisir les informations concernant un livre.
exemple : pour le livre de lexemple prcdent :
Entrez
Entrez
Entrez
Entrez
Entrez
Entrez

TP 37

le code : AGZ12
la date de publication :
le jour : 12
le mois : 10
lannee : 2004
le nombre dexemplaires : 3

Algorithmique et programmation

1/3

stock dune librairie

Entrez le prix de lexemplaire 1 : 12.5


Entrez le prix de lexemplaire 2 : 20
Entrez le prix de lexemplaire 3 : 12.3

3 Enregistrement & chargement


Exercice 4
Dans la bibliothque livre, crivez une fonction void sauve_livre(t_livre livre,
FILE *f) qui enregistre le livre pass en paramtre dans le fichier dsign par f (on suppose
que le fichier a dj t ouvert en criture).
Remarque : dans le fichier cr, sparez les champs en utilisant des tabulations '\t'.

Exercice 5
Dans la bibliothque livre, crivez une fonction void charge_livre(t_livre*
livre, FILE *f) qui charge un livre dans le fichier dsign par f (on suppose que le fichier
a dj t ouvert en lecture), et qui passe ce livre par adresse.

4 Stock de la librairie
On utilise un tableau de type t_livre pour reprsenter tous les livres stocks dans la
librairie. On suppose que la librairie peut stocker seulement un nombre fini N dexemplaires :
ce tableau peut donc tre allou de faon statique, puisquon sait quil contiendra au
maximum N livres.

Exercice 6
Dans la bibliothque livre, crivez une fonction void saisis_stock(t_livre
stock[N], int* n) qui permet de saisir tous les livres constituant le stock dune librairie.
Le tableau reu est suppos initialement vide. La fonction doit utiliser saisis_livre pour le
remplir, et permettre lutilisateur de sarrter quand il le souhaite, comme dans lexemple cidessous. De plus, elle doit vrifier que lutilisateur ne saisit pas plus de N livres. Le paramtre
n sert renvoyer par adresse le nombre de livres saisis.
exemple :
Livre 1 :
Entrez le code : AGZ12
Entrez la date de publication :
Entrez le jour : 12
Entrez le mois : 10
Entrez lannee : 2004
Entrez le nombre dexemplaires : 3
Entrez le prix de lexemplaire 1 : 12.5
Entrez le prix de lexemplaire 2 : 20
Entrez le prix de lexemplaire 3 : 12.3
Voulez-vous saisir un autre livre (O/N) ? O
Livre 2 :
Entrez le code : ZZX38
Entrez la date de publication :
Entrez le jour : 5
Entrez le mois : 4
Entrez lannee : 2014
Entrez le nombre dexemplaires : 5
Entrez le prix de lexemplaire 1 : 99.99
Entrez le prix de lexemplaire 2 : 100
Entrez le prix de lexemplaire 3 : 122
Entrez le prix de lexemplaire 4 : 92
Entrez le prix de lexemplaire 5 : 100.50
Voulez-vous saisir un autre livre (O/N) ? N
Termine : 2 livres ont t saisis

TP 37

Algorithmique et programmation

2/3

stock dune librairie

Exercice 7
Dans la bibliothque livre, crivez une fonction void affiche_stock(t_livre
stock[N], int n) qui affiche les n livres contenus dans le tableau stock pass en paramtre,
la manire de lexemple ci-dessous.
exemple : pour les livres saisis dans lexemple prcdent
1.AGZ12 - 12 octobre 2004 - 3 exemplaires : 12.50 20.00 12.30
2.ZZX38 5 avril 2014 5 exemplaires : 99.99 100.00 122.00 92.00 100.50

Exercice 8
Dans la bibliothque livre, crivez une fonction void sauve_stock(t_livre
stock[N], int n, char* fichier) qui reoit en paramtre un tableau reprsentant le
stock de la librairie, et une chane de caractres reprsentant le nom dun fichier. La fonction
doit ouvrir ce fichier en criture, et y enregistrer les n livres prsents dans le stock. Bien sr,
la fonction doit utiliser sauve_livre.
Testez votre fonction en saisissant quelques livres avec saisis_stock, puis en
enregistrant avec sauve_stock le stock obtenu, et enfin en visualisant directement dans
Eclipse le contenu du fichier texte ainsi produit.

Exercice 9
Dans la bibliothque livre, crivez une fonction void charge_stock(t_livre
stock[N], int* n, char* fichier) qui reoit en paramtre un tableau reprsentant le
stock de la librairie, qui est pour linstant vide, et une chane de caractres reprsentant le nom
dun fichier. La fonction doit ouvrir ce fichier en lecture, et en charger tous les livres
contenus, pour les placer le tableau stock. Bien entendu, la fonction doit utiliser
charge_livre. Le paramtre n sert renvoyer par adresse le nombre de livres lus dans le
fichier.
Testez votre fonction en ditant, directement dans Eclipse, le fichier texte produit
lexercice prcdent, de faon le complter avec quelques livres supplmentaires ; puis en
chargeant ce fichier avec charge_stock et enfin en laffichant avec affiche_stock.

5 Oprations sur le stock


Exercice 10
Dans la bibliothque livre, crivez une fonction int compte_exemplaires(t_livre
stock[N], int n) qui compte le nombre dexemplaires en stock.

Exercice 11
Dans la bibliothque livre, crivez une fonction float estime_stock(t_livre
stock[N], int n) qui reoit en paramtre un stock (tableau de livres stock et nombre de
livres n), et qui calcule et renvoie la valeur marchande du stock, i.e. la somme des prix de tous
les exemplaires stocks.
exemple : pour le stock des exemples prcdents, la fonction doit renvoyer
.

TP 37

Algorithmique et programmation

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 38

automates cellulaires

Prsentation
Dans ce TP, nous allons utiliser nos connaissances sur les matrices, les fichiers et
lallocation dynamique pour implmenter des automates cellulaires simples. On sintressera
en particulier au jeu de la vie de Conway.

1 Dfinition
Un automate cellulaire est un ensemble de cellules disposes de faon gomtrique, par
exemple sous forme de grille 2D comme ci-dessous. Chaque cellule est caractrise par son
tat, qui est une valeur discrte. Dans le cas le plus simple, ltat est binaire : la cellule est soit
morte, soit vivante.

Ltat dune cellule un instant donn dpend des tats de ses voisines linstant
prcdent
. Le voisinage dune cellule peut tre dfini de diffrentes faons. Ainsi, dans
lexemple ci-dessus, on considre que les cellules colores en bleu sont les voisines de la
cellule colore en rouge. La fonction utilise pour mettre jour ltat dune cellule en
fonction des tats de ses voisines peut prendre de nombreuses formes.
Ltude des automates cellulaires fait partie de linformatique thorique, et permet de
modliser et de comprendre les proprits de systmes dynamiques complexes. La forme
dautomate cellulaire la plus connue est le Jeu de la vie, dfini par John Conway dans les
annes 1970. Les tats sont binaires, et les cellules sont rparties comme dans la figure cidessus, avec le mme voisinage que celui donn en exemple. La rgle de mise jour des tats
est la suivante :
Si une cellule est morte :
o Si elle possde exactement voisines vivantes, elle renait (elle devient
vivante).
o Sinon, elle reste morte.
Si une cellule est vivante :
o Si elle possde exactement ou voisines vivantes, elle reste vivante.
o Sinon, elle meurt.
Dans la figure ci-dessus, les cases sombres reprsentent des cellules vivantes. La cellule
rouge est morte, et elle possde 4 cellules vivantes dans son voisinage, donc elle va rester
dans cet tat (morte).

TP 38

Algorithmique et programmation

1/4

automates cellulaires

2 Reprsentation
On va reprsenter un automate cellulaire par une matrice de
reprsentant une cellule morte et la valeur une cellule vivante.

entiers, la valeur

Exercice 1
Les fonctions concernant les automates cellulaires vont tre places dans une bibliothque
spciale appele automate, qui utilisera la bibliothque graphisme pour donner une
reprsentation graphique. Crez les fichiers ncessaires, et dclarez les constantes N et M.
Remarque : pour des raisons esthtiques, utilisez des valeurs multiples de la rsolution de
la fentre graphique (cf. les constantes dans la bibliothque graphisme). Par exemple,
et
.

Exercice 2
automate,
crivez
une
fonction
void
vide_automate(int
automate[N][M]) qui reoit une matrice reprsentant un automate, et qui place toutes ses

Dans

cellules ltat mort (i.e. valeur ).

Exercice 3
automate,
crivez
une
fonction
void
copie_automate(int
er
automate1[N][M], int automate2[N][M]) qui recopie les tats des cellules du 1

Dans

automate dans celles du 2nd.

Exercice 4
automate,
crivez une fonction void
dessine_automate(int
automate[N][M]) qui dessine lautomate dans la fentre graphique, en utilisant au

Dans

maximum lespace disponible. Les cellules vivantes doivent tre reprsentes en blanc, les
mortes en noir, et un quadrillage gris doit tre trac par-dessus, comme dans les captures qui
suivent.

3 Simulation
Exercice 5
Dans automate, crivez une fonction int compte_voisines_vivantes(int
automate[N][M], int i, int j) qui compte le nombre de cellules vivantes dans le
voisinage de la cellule situe la position ( ) dans la matrice formant lautomate.
Remarque : si le voisinage est incomplet parce que la cellule se trouve en bordure de
matrice, on considre les cellules manquantes comme mortes.

Exercice 6
Dans
automate,
crivez
une
fonction
void
itere_automate(int
automate[N][M]) qui met jour toutes les cellules de lautomate. La fonction doit
renvoyer si au moins une cellule a chang dtat, et si aucune na chang dtat.
Remarque : la fin du traitement, la matrice automate doit contenir les tats mis jour.
Cependant, le calcul de mise jour ncessite dutiliser la matrice originale. Il est donc
ncessaire de la copier grce la fonction copie_automate.

Exercice 7
automate,
crivez
une
fonction
void
simule_automate(int
automate[N][M], int iterations) qui effectue plusieurs itrations de mise jour de
lautomate. Si la valeur du paramtre iterations est , alors la fonction doit effectuer des

Dans

TP 38

Algorithmique et programmation

2/4

automates cellulaires

mises jour tant quau moins une cellule change dtat. Si la valeur de iterations est un
entier non-nul, alors la fonction doit effectuer le nombre indiqu ditrations.
chaque itration effectue, la fonction doit dessiner lautomate obtenu, et attendre un
certain temps grce attends_delai.

Exercice 8
Pour tester vos fonctions, initialisez un automate zro avec vide_automate, puis
construisez les deux figures suivantes :
Un bloc de
cellules vivantes ;
Un vecteur de
cellules vivantes.

La premire figure (bloc) ne doit pas voluer au cours des itrations, alors que la seconde
(vecteur) va alterner entre les formes horizontales et verticales du vecteur, comme reprsent
ci-dessus.

4 Structures cellulaires
Une part importante du travail sur les automates cellulaires consiste identifier des
structures cellulaires, i.e. des groupes de cellules possdant des proprits particulires. Le
bloc et le vecteur donns en exemple dans lexercice prcdent sont des structures cellulaires :
le premier est une structure stable alors que le second est un oscillateur.

Exercice 9
Le dossier structures fourni avec ce sujet contient plusieurs structures diffrentes,
reprsentes sous formes de fichiers textes. La forme de ces fichiers textes est la suivante :
Les nombres de lignes et de colonnes dans la structure, spars par une tabulation ;
Une matrice reprsentant la structure, dont les valeurs sont spares par des
tabulations.
exemple : la structure vecteur de lexemple prcdent est reprsente de la faon suivante
(les underscores '_' reprsentent des tabulations)
5__5
0__0__0__0__0__
0__0__0__0__0__
0__1__1__1__0__
0__0__0__0__0__
0__0__0__0__0__

Aprs avoir tudi attentivement ce format de fichier, crivez dans automate une
fonction int charge_structure(char* fichier, int** structure, int*
lignes, int* colonnes) qui charge la structure cellulaire contenue dans le fichier dont
le nom fichier est pass en paramtre.
Cette fonction doit allouer dynamiquement la place ncessaire la matrice reprsentant la
structure cellulaire, puis initialiser cette matrice avec les valeurs contenues dans le fichier.
Elle doit renvoyer
en cas derreur, et en cas de succs. Notez bien que les dimensions de
la matrice, ainsi que la matrice elle-mme, sont passes par adresse.

TP 38

Algorithmique et programmation

3/4

automates cellulaires

Exercice 10
Dans automate, crivez une fonction void
ajoute_structure(int
automate[N][M], int* structure, int lignes, int colonnes, int i, int
j) qui place la structure cellulaire spcifie la position spcifie dans lautomate pass en
paramtre. Autrement dit, la fonction va recopier le contenu de la matrice reprsentant la
structure cellulaire lendroit appropri dans la matrice reprsentant lautomate cellulaire.
Llment ( ) de structure doit tre plac la position ( ) de automate, et ainsi de
suite.

Exercice 11
On peut maintenant jouer avec les diffrents types de structures existant :
Statique : structure qui est stable dans le temps, i.e. si on ne la perturbe pas, elle
nvolue pas du tout.
Oscillateur : structures qui volue dans le temps, mais qui est caractrise par un
cycle, i.e. elle revient toujours sa forme initiale, aprs un nombre fini dtapes.
Vaisseau : structure qui ressemble un oscillateur, la diffrence quelle se
dplace.
Puffeur : structure qui ressemble un vaisseau, la diffrence quelle laisse de
nouvelles structures derrire elle au cours de son dplacement.
Canon : structure qui ressemble un oscillateur, la diffrence quelle produit des
vaisseaux.
Mathusalem : structure relativement simple, mais instable et qui prend un grand
nombre ditrations avant de se stabiliser.
Les vaisseaux, en particulier sont caractriss par leur vitesse, exprime en nombre de
cellules par itration. Quelle sont les vitesses des vaisseaux proposs sous forme de fichiers
texte ? Pouvez-vous en proposer un plus rapide ?

TP 38

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 39

fonctions rcursives

Prsentation
Le but de ce TP est dcrire des fonctions rcursives simples. On les appliquera
diffrents types de donnes : chanes de caractres et entiers. Les exercices de ce TP sont
indpendants : vous ne devez pas rutiliser les fonctions prcdentes (sauf si le contraire est
explicitement indiqu).

1 Chanes de caractres
Exercice 1
crivez une fonction est_contenu qui reoit en paramtres une chane de caractres
chaine et un caractre c. La fonction doit rcursivement chercher c dans chaine. Si c est

contenu dans chaine, la fonction doit renvoyer , sinon, elle doit renvoyer .
exemples :
Pour chaine="edbac" et c='b' la fonction doit renvoyer .
Pour chaine="edbac" et c='f' la fonction doit renvoyer .

Exercice 2
crivez une fonction compte_occurrences qui reoit en paramtres une chane de
caractres chaine et un caractre c. La fonction doit calculer rcursivement le nombre
doccurrences de c dans chaine (i.e. le nombre de fois que c apparat).
Remarque : il sagit dune variable c, et non pas de la valeur littrale 'c'.
exemples :
Pour chaine="aedabac" et c='a' la fonction doit renvoyer .
Pour chaine="aedabac" et c='b' la fonction doit renvoyer .
Pour chaine="aedabac" et c='f' la fonction doit renvoyer .

Exercice 3
crivez une fonction calcule_longueur qui reoit en paramtre une chane de
caractres chaine, calcule rcursivement sa longueur (sans compter le '\0') et la renvoie
par valeur.

Exercice 4
crivez une fonction calcule_position qui reoit en paramtres une chane de
caractres chaine et un caractre c. La fonction doit rcursivement chercher c dans chaine.
Si c est contenu dans chaine, la fonction doit renvoyer par valeur la position de sa premire
occurrence. Sinon, elle doit renvoyer
.
exemples :
pour chaine="edbac" et c='b' la fonction doit renvoyer .
pour chaine="edbac" et c='f' la fonction doit renvoyer
.

TP 39

Algorithmique et programmation

1/3

fonctions rcursives

2 Entiers
Exercice 5
On considre la suite de Fibonacci dfinie par (pour

):

{
crivez une fonction calcule_fibonacci qui reoit n en paramtre, calcule
rcursivement le terme , puis le renvoie par valeur.
Donnez larbre des appels pour
. En observant larbre obtenu, pensez-vous quil
serait possible dcrire une fonction plus rapide ?

Exercice 6
On veut calculer rcursivement le plus grand commun diviseur (PGCD) de deux nombres
(
). On sait que :
Si lun des deux nombres est nul, alors le PGCD est lautre nombre.
Sinon :
) est gal celui de (
).
o si
alors le PGCD de (
) est gal celui de (
).
o si
alors le PGCD de (
crivez une fonction calcule_pgcd recevant deux paramtres x et y, calculant
rcursivement leur PGCD, et le renvoyant par valeur.

Exercice 7
Le calcul de

peut se faire l'aide de la relation de rcurrence suivante :


{

( )
( )

crivez une fonction long calcule_puissance(long x, long y) qui applique


cette relation pour calculer .
Donnez larbre des appels pour
et
. Cette mthode est-elle plus ou moins
efficace que celle vue en cours ?

3 Chanes de caractres (suite)


Exercice 8
Un nombre romain peut se composer des chiffres suivants (reprsents par des lettres
majuscules) :

De plus, un nombre romain est interprt grce aux rgles suivantes :


Si le nombre ne contient quun seul chiffre, alors la valeur du nombre est gale
celle du chiffre.
Si le nombre contient au moins deux chiffres, on considre les deux chiffres les
plus gauche :
o Si le 1er chiffre est suprieur ou gal au 2me, alors la valeur du nombre est
gale la somme du 1er chiffre et de la valeur du nombre compos des
chiffres restants.
o Si le 1er chiffre est infrieur au 2me, alors la valeur du nombre est gale la
diffrence entre la valeur du nombre compos des chiffres restants et le 1er
chiffre.

TP 39

Algorithmique et programmation

2/3

fonctions rcursives

exemples :

crivez dabord une fonction int evalue_chiffre_romain(char chiffre), qui


nest pas rcursive, et qui renvoie la valeur numrique associe au chiffre romain pass en
paramtre sous la forme dun simple caractre.
Ensuite, crivez une fonction int evalue_nombre_romain(char *nombre) qui
reoit en paramtre un nombre romain reprsent par une chane de caractres, et qui renvoie
par valeur le rsultat de lvaluation rcursive de ce nombre. Vous devez bien sr utiliser
evalue_chiffre_romain.
Remarque : on suppose que la syntaxe du nombre est correcte, inutile de la vrifier.

Exercice 9
On dit quune chane de caractres chaine1 est un prfixe dune autre chane chaine2
ssi la chane chaine1 correspond exactement au dbut de la chane chaine2.
exemples :
"bon" est un prfixe de "bonjour".
"bonne" nest pas un prfixe de "bonjour".
"bonne" nest pas un prfixe de "bon".
"" (chane vide) est prfixe de nimporte quelle chane.
crivez une fonction rcursive int est_prefixe(char* chaine1, char*
chaine2) qui renvoie si chaine2 est un prfixe de chaine1, et sinon.
Donnez larbre des appels pour les appels suivants :

est_prefixe("bon", "bonjour")
est_prefixe("bonne", "bonjour")

Exercice 10
On dit que la chane chaine1 contient une autre chaine chaine2 ssi la chane chaine2
est un prfixe dune sous-chane de chaine1. De faon quivalente, on dit aussi que
chaine2 est contenue dans chaine1.
exemples :
"njo" est contenue dans "bonjour".
"onje" nest pas contenue dans "bonjour".
"bonjour" nest pas contenue dans "onj".
Aucune chane non vide nest contenue dans la chane vide "".
crivez une fonction rcursive int est_contenue(char* chaine1, char*
chaine2) qui dtermine si la chane de caractres chaine1 est contenue dans la chaine
chaine2. Elle renvoie
si cest le cas, et
sinon. Vous devez utiliser la fonction
est_prefixe.
Donnez ensuite larbre des appels pour les appels suivant :

est_contenue("njo","bonjour")
est_contenue("onje","bonjour")

Exercice 11
crivez une fonction rcursive void ftnirp(char *chaine) qui affiche une chane de
caractres lenvers, sans la modifier.
exemple : ftnirp("abcdef") doit afficher fedcba.

TP 39

Algorithmique et programmation

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut

TP 40

Universit
Galatasaray

approximations numriques

Prsentation
Le but de ce TP est dutiliser les notions vues jusqu prsent en cours et TP, en les
appliquant deux problmes dapproximation numrique. On sintressera dabord la
fonction cosinus, puis la constante .

1 Dveloppement en srie entire


( ) en utilisant le dveloppement en

Pout tout rel , on peut calculer la valeur de


srie entire de la fonction cosinus :
( )

( ), on peut ne calculer que les

Pour obtenir une valeur approche de


termes de ce dveloppement :
( )

premiers

Pour que lapproximation soit bonne, il faut choisir une valeur de qui dpend de . En
pratique, cette formule devient incalculable pour un ordinateur, mme pour des valeurs de
assez petites (par exemple
). Par contre pour des valeurs telles que | |
, elle peut tre
utilise.

Exercice 1
crivez une fonction rcursive int calcule_factorielle(int n) qui calcule et
renvoie .
exemple :

Exercice 2
crivez une fonction rcursive double calcule_puissance(double x, int n)
qui calcule
en utilisant le principe de lexponentiation rapide suivant :
{

( )
( )

exemple :

Exercice 3
crivez une fonction double calcule_cosinus(double theta, double delta)
qui utilise le principe dapproximation par srie entire dcrit en dbut de section, pour
calculer le cosinus de theta. Votre fonction utilisera les fonctions des deux exercices
prcdents.

TP 40

Algorithmique et programmation

1/3

approximations numriques

Au lieu dutiliser une valeur fixe lavance, on spcifiera une valeur correspondant
un changement minimal dans le principe itratif suivant :
er
On calcule le 1 terme du dveloppement.
me
On calcule le 2
terme du dveloppement.
On les additionne pour obtenir une approximation du cosinus.
Tant que la valeur absolue du dernier terme calcul est suprieure :
o On calcule le terme suivant, quon ajoute lapproximation du cosinus.
On sarrte donc quand un terme ne modifie plus lapproximation de faon significative.
Pour des raisons de dbogage, votre fonction doit afficher lvolution de lapproximation
et les termes calculs, comme indiqu ci-dessous. De plus, vous devez afficher 10 chiffres
aprs la virgule, afin de pouvoir observer lvolution de la prcision jusquau bout du
traitement.
exemple : affichage obtenu pour lapproximation de , avec delta=e-8 :
i=0
1.0000000000
i=1
1.0000000000 - 0.1370697535 = 0.8629302465
i=2
0.8629302465 + 0.0031313529 = 0.8660615994
i=3
0.8660615994 - 0.0000286143 = 0.8660329852
i=4
0.8660329852 + 0.0000001401 = 0.8660331252
i=5
0.8660331252 - 0.0000000004 = 0.8660331248
cos(0.523583)~0.866033 vs. cos(0.523583)=0.866033

Remarque : dans la dernire ligne de laffichage, on compare la valeur estime et celle


calcule avec la bibliothque mathmatique math.h.

2 Mthode de Monte-Carlo
Lexpression Monte-Carlo dsigne une famille de mthodes reposant sur le hasard pour
estimer certaines valeurs. Dans notre cas, nous voulons estimer la valeur de .
Considrons la figure suivante, qui reprsente le 1er quadrant du disque-unit :

On a les aires suivantes :


Aire du quart-de-disque :
Aire du carr :
.
Supposons quon tire au sort un point dans le carr considr, de faon uniforme (i.e.
chaque coordonne a la mme chance dtre tire que nimporte quelle autre). Alors la
probabilit que ce point soit situ dans le disque est gale la proportion de laire du carr

occupe par le quart-de-disque, i.e.


. Par consquent, on a
.
Donc, si on russit estimer , on aura aussi estim . Une mthode simple consiste :
Tirer un grand nombre
de points dans le carr ;
Compter le nombre
de ces points qui sont tombs dans le quart-de-disque.
, i.e. la proportion de points tirs tombs dans le quart-de-disque.
Alors

Exercice 4

TP 40

Algorithmique et programmation

2/3

approximations numriques

crivez une fonction double tire_reel() qui tire au sort une valeur relle comprise
entre et (inclus).
Rappel : pour tirer une valeur au hasard en langage C, vous devez utiliser les fonctions
srand et rand. La premire sert initialiser la graine du gnrateur pseudo-alatoire, en
gnral en utilisant la fonction time de la bibliothque time.h. La seconde sert tirer une
valeur entire comprise entre et RAND_MAX (incluses). Pour plus de dtails, voyez les TP
concerns.

Exercice 5
crivez une fonction void calcule_pi(int nc) qui calcule en utilisant la mthode
dcrite ci-dessus. Le paramtre nc correspond au nombre de points tirer dans le carr.
Testez la prcision de cette mthode partir de la fonction main, en utilisant des valeurs
de nc de plus en plus grandes, comme dans lexemple ci-dessous.
exemple : estimations obtenues pour quelques valeurs croissantes de nc :
5
10
100
1000
10000
100000
1000000
10000000
100000000
1000000000

points
points
points
points
points
points
points
points
points
points

:
:
:
:
:
:
:
:
:
:

pi~2.400000
pi~3.600000
pi~2.920000
pi~3.160000
pi~3.152400
pi~3.147040
pi~3.142104
pi~3.141124
pi~3.141719
pi~3.141502

Remarque : bien sr, cause de laspect alatoire de cette approche, chaque excution est
susceptible de produire des rsultats lgrement diffrents.

TP 40

Algorithmique et programmation

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 41

figures fractales

1 Prsentation
Une figure fractale est construite en rptant un motif
linfini : si on agrandit la figure, on retrouve le mme motif.
Ce type de construction se retrouve frquemment dans la
nature : cristaux, vgtaux, etc. La programmation rcursive
est tout particulirement adapte la reproduction de figures
fractales.
Pour dessiner ces figures, vous utiliserez la SDL. Dans
Eclipse, crez un nouveau projet, et configurez-le pour la
SDL1. Puis, copiez-y les fichiers contenus dans larchive qui
accompagne ce sujet. Ceux-ci dfinissent la bibliothque
graphisme, dj utilise prcdemment.
Vous devez galement configurer votre projet pour
lutilisation de la librairie math.h. Vous aurez besoin de ses
fonctions suivantes :
double sqrt(double x) : calcule la racine carre dun nombre x.
double sin(double a) : calcule le sinus de langle a exprim en radians.
double cos(double a) : calcule le cosinus de langle a exprim en radians.

2 Flocon de von Koch


Un segment de von Koch est une figure fractale obtenue en partant d'un segment [

]:

E
A

On partage ce segment [

] en trois parties [

], [

] et [

] de longueurs gales :
E

On place le point

D
B

de manire ce que (

) forme un triangle quilatral :


C
D

Dans le cas le plus simple du segment de von Koch, on trace les segments [
] et [ ] afin dobtenir la figure suivante :

TP 41

Algorithmique et programmation

], [

],

1/5

figures fractales

C
D
B

Cependant, pour obtenir leffet fractal, il faut rpter rcursivement cette construction.
Pour cela, au lieu de tracer les segments comme ci-dessus, on applique une autre fois la mme
transformation, mais cette fois-ci aux segments [ ], [ ], [ ] et [ ]. On obtient le
rsultat suivant :

Et aprs avoir trac les segments appropris, on a :

On rpte rcursivement le procd pour obtenir une figure fractale. Si on ralise


itrations, on obtient la figure suivante :

Et si on fait

itrations, on a :

Si on applique ce traitement non pas un seul segment, mais aux trois cts dun triangle
quilatral, on obtient un flocon de von Koch complet :

TP 41

Algorithmique et programmation

2/5

figures fractales

Exercice 1
Calculez les coordonnes des points ,
. Vous remarquerez que est limage de

et en fonction des coordonnes des points


par la rotation daxe et dangle

et

C
D

B
A

Rappel : les coordonnes de limage (


et de centre lorigine ( ) sont :

) dun point (
( )
( )

) par une rotation dangle

( )
( )

Crez un fichier main.c et crivez une fonction void calcule_segment_vonkoch(int


xa, int ya, int* xb, int* yb, int* xc, int* yc, int* xd, int* yd, int xe,
int ye) qui reoit en paramtres les coordonnes des points et de la figure prcdente, et
calcule les coordonnes des points ,

et

(attention aux passages par adresse !).

Exercice 2
Vrifiez vos calculs en crivant une fonction void teste_segment_vonkoch(int xa,
int ya, int xe, int ye) qui reoit en paramtres les coordonnes des points et de la
figure simple prcdente, et trace les segments [

], [

], [

], et [

].

Exercice 3
En utilisant calcule_segment_vonkoch, crivez une fonction rcursive void
trace_segment_vonkoch(int x1, int y1, int x2, int y2, int n) qui dessine la

TP 41

Algorithmique et programmation

3/5

figures fractales

figure obtenue en appliquant n fois la mthode de von Koch au segment de coordonnes


(x1,y1) et (x2,y2).

Exercice 4
En utilisant la fonction segment_von_koch, crivez une fonction void
trace_flocon_vonkoch(int n) qui dessine au centre de lcran un flocon de von Koch en
appliquant n fois la mthode de von Koch chacun des cts d'un triangle quilatral.
Pour que la figure soit trace pas pas, vous devez utiliser les fonctions attends_delai
et rafraichis_fenetre de manire introduire un dlai entre le trac de chaque segment.

3 Fractale arborescente
En utilisant le mme principe, il est possible de crer des figures fractales partir de
nombreuses figures gomtriques diffrentes. Prenons un arbre binaire (i.e. deux branches) :
A
B

On part dun segment [ ] que lon partage en deux en plaant un point


tel que
avec
. Puis, on obtient les points et par rotations de centre et
dangles respectifs et (ces deux angles peuvent tre diffrents).
On rpte ensuite rcursivement le traitement sur [ ] et [ ], ainsi que sur leurs soussegments, pour obtenir la figure fractale. En ritrant le traitement fois, on obtient larbre
suivant :

Et en le ritrant

TP 41

et

fois :

Algorithmique et programmation

4/5

figures fractales

Exercice 5
crivez une fonction void calcule_segment_fractarbre(int xa, int ya, int*
xb, int* yb, int* xc, int* yc, int* xd, int* yd, int xe, int ye) qui calcule
les coordonnes des points ,

et

partir de celles de

et .

Exercice 6
Vrifiez vos calculs en crivant une fonction void teste_segment_fractarbre(int
xa, int ya, int xe, int ye) qui reoit en paramtres les coordonnes des points et
de la figure simple prcdente, et trace les segments [ ], [ ], et [ ].

Exercice 7
crivez une fonction rcursive void trace_arbre(int x_1, int y_1, int x_2, int
y_2, int n) qui dessine la courbe obtenue en appliquant n fois la mthode prcdente au
segment de coordonnes (x_1,y_1) et (x_2,y_2). Vous utiliserez les paramtres suivants :
et
.
;

TP 41

Algorithmique et programmation

5/5

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 42

listes chanes

Prsentation
Le but de ce TP est dutiliser les listes chanes vues en cours. Les deux bibliothques
liste_s (listes simples) et liste_d (listes doubles) correspondant aux structures de donnes

et fonctions tudies en cours sont fournies avec ce sujet. Vous devez crire vos propres
fonctions dans le fichier main.c.

1 Oprations sur une liste simple


Exercice 1
crivez une fonction int remplis_liste(int tab[], int taille, liste_s *l) qui
reoit ladresse dune liste vide dj initialise et la remplit avec les valeurs contenues dans le
tableau pass en paramtre. La fonction renvoie
si une erreur se produit, et sinon.
exemple : pour tab={1,5,18,-1,4,0}, on obtient la liste suivante :
1

18

-1

0 NULL

Exercice 2
crivez une fonction int calcule_longueur(liste_s l) qui renvoie le nombre
dlments prsents dans la liste l passe en paramtre.

Exercice 3
crivez une fonction int recherche_valeur(liste_s l, int v) qui recherche une
valeur v dans une liste simplement chane l (qui nest pas ordonne). La fonction doit
renvoyer la position de la premire occurrence de la valeur dans la liste, ou
si la liste ne
contient pas dlments de valeur v.
exemple :
1

18

-1

0 NULL

Si on recherche la valeur
dans la liste ci-dessus, la fonction doit renvoyer . Si on
recherche la valeur , elle doit renvoyer
.

Exercice 4
crivez une fonction void melange_liste(liste_s *l) qui prend un pointeur sur une
liste simplement chane en paramtre, et dont le rle est de :
1. couper la liste en deux, la moiti ( un lment prs si la taille est impaire)
2. intervertir les deux moitis.
exemple :

TP 42

Algorithmique et programmation

1/4

listes chanes

liste de dpart
1

18

-1

0 NULL

liste

tape 1)
1

18 NULL

-1

0 NULL

18 NULL

-1

liste

tape 2)
1

liste

liste rsultat
-1

18 NULL

liste

2 Oprations sur plusieurs listes simples


Exercice 5
crivez une fonction void fusionne_listes(liste_s *l1, liste_s l2) qui prend
en paramtres un pointeur sur une liste simplement chane l1, et une liste simplement
chane l2. La fonction doit rajouter la liste l2 la fin de la liste l1.
exemple :
liste 1 avant la fusion
1

18 NULL

liste 2
32

-1

0 NULL

liste 1 aprs la fusion


1

18

32

-1

0 NULL

Exercice 6
On dit quune liste l2 prfixe une liste l1 si l2 apparat entirement au dbut de l1.
exemples :
l1
{1,
{1,
{1,
{}
{1,
{1,
{1,
{1,

TP 42

2, 4, 8, 0, 3}
2, 4, 8, 0, 3}
2, 4, 8}
2,
2,
2,
2,

4,
4,
4,
4,

8,
8,
8,
8,

0,
0,
0,
0,

3}
3}
3}
3}

l2
{1,
{1}
{1,
{}
{}
{5,
{4,
{1,

2, 4}
2, 4, 8}

6}
8, 0}
2, 4, 8, 0, 3, 7}

Algorithmique et programmation

prfixe ?
oui
oui
oui
oui
oui
non
non
non

2/4

listes chanes

crivez une fonction rcursive int est_prefixe(liste_s l1, liste_s l2) qui prend
deux listes l1 et l2 en paramtres, et renvoie un entier indiquant si l2 est prfixe de l1.
Lentier doit valoir pour oui et pour non.

3 Oprations sur une liste double


Exercice 7
crivez une fonction int echange_elements(liste_d *l, int p, int q) qui
intervertit les lments dune liste l doublement chane situs aux positions p et q. La
fonction renvoie en cas de succs ou
en cas derreur.
exemple : si on applique la fonction la liste 1,25,34,59,2,6 et aux lments situs
aux positions 2 et 4, on obtient la liste 1,25,2,59,34,6.

Exercice 8
Compltez la fonction int detache_element(liste_d *l, element_d *e) qui
enlve llment e de la liste l. Attention, llment ne doit pas tre supprim : il sagit
seulement de modifier les pointeurs des lments de l de manire ce que e nen fasse plus
partie.
exemple :
e

Avant lappel :
NULL 1

18

0 NULL

NULL 7 NULL

Aprs lappel :
NULL 1

18

0 NULL

Si la liste l ne contient pas llment e, la fonction doit renvoyer


, et sinon elle doit
renvoyer . Il est alors recommand de distinguer les 4 cas suivants :
La liste contient un seul lment (qui est bien sr e) ;
La liste contient plusieurs lments et e est au dbut ;
La liste contient plusieurs lments et e est la fin ;
La liste contient plusieurs lments et e nest ni au dbut, ni la fin.

Exercice 9
crivez une fonction void inverse_liste(liste_d *l) qui inverse lordre des
lments dune liste l. Votre fonction devra utiliser la fonction detache_element_d.
exemple :

TP 42

Algorithmique et programmation

3/4

listes chanes

Avant lappel :
NULL 1

18

0 NULL

18

1 NULL

Aprs lappel :
NULL 0

7
l

TP 42

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 43

disques & guirlandes

Prsentation
Le but de ce TP de manipuler des listes en traant diffrentes figures base de disques.
Pour cela, on utilisera la SDL, et la bibliothque graphisme qui est fournie avec ce sujet.
Cependant, ne configurez pas encore le projet pour utiliser la SDL, car les premiers exercices
du TP ncessitent dafficher du texte dans la console.
La bibliothque liste_s est aussi fournie avec le sujet, pour la manipulation de listes
simplement chanes. Les fonctions et types crits au cours du TP seront placer dans lune
des deux nouvelles bibliothques que vous devrez crer : disque et guirlande.

1 Points
Exercice 1
Crez une nouvelle bibliothque appele disque. Dans cette bibliothque, dfinissez un
type structur t_point, permettant de reprsenter un point du repre en utilisant ses deux
coordonnes x et y, toutes les deux exprimes en pixels.

Exercice 2
Dans disque, crivez une fonction void affiche_point(t_point p) qui affiche le
point p sous forme de texte, dans la console.
) sera affich de la faon suivante :
exemple : le point de coordonnes (
(12,13)

2 Disques
Exercice 3
Dans disque, dfinissez un type structur t_disque permettant de reprsenter un disque
grce son centre (un point) et son rayon exprim en pixels. Vous devez bien entendu
utiliser le type t_point.

Exercice 4
Dans disque, crivez une fonction void affiche_disque(t_disque d) qui affiche
le disque d sous forme de texte, dans la console.
) et de rayon sera affich de la faon suivante :
exemple : le disque de centre (
(c : (12,13), r : 9)

Exercice 5
Dans disque, crivez les fonctions void modifie_centre(t_disque* d, int
d_x, int d_y) et void modifie_rayon(t_disque* d, int d_r) qui permettent
respectivement de modifier le centre et le rayon dun disque existant.
exemples :

TP 43

Algorithmique et programmation

1/4

disques & guirlandes

Si on appelle modifie_centre sur le disque de lexemple prcdent, avec


et
, laffichage du rsultat donne :

(c : (22,63), r : 9)

Si on appelle modifie_rayon sur le disque de lexemple prcdent, avec


, laffichage du rsultat donne :

(c : (12,13), r : 109)

Exercice 6
Dans disque, crivez la fonction t_disque genere_disque() qui gnre un disque
en slectionnant alatoirement un centre et un rayon.
Rappel : la gnration dun nombre alatoire en C passe par les fonctions
srand(time(NULL)) (pour linitialisation de la srie pseudo-alatoire) et rand() (pour
tirer un nombre entier compris entre
et RAND_MAX), contenues toutes les deux dans
stdlib. La fonction time est, elle, contenue dans time.h.
Remarque : vous avez besoin des constantes FENETRE_LARGEUR et FENETRE_HAUTEUR
dfinies dans graphisme, donc il est ncessaire dinclure cette bibliothque dans disque.

Exercice 7
Configurez votre projet pour utiliser la SDL. Notez que la bibliothque graphisme
contient une fonction dessine_disque, permettant dafficher un disque en prcisant la
position de son centre et la couleur utiliser.
laide de cette fonction, crivez dans disque une fonction void anime_disque()
qui affiche un disque traversant lcran de la gauche vers la droite, en augmentant
progressivement son diamtre.
Remarque : vous devez utiliser la fonction attends_delai(temps) pour ralentir
lexcution, o temps est une dure exprime en ms. Pensez aussi utiliser les fonctions des
exercices prcdents. Pensez aussi utiliser rafraichis_fenetre quand cest ncessaire.
exemple :

3 Guirlandes
Exercice 8
On veut maintenant reprsenter une guirlande en utilisant une liste de disques. Modifiez
dabord la bibliothque liste_s fournie avec ce sujet, afin quelle manipule des disques au
lieu dentiers :
Changez son nom en liste_s_disque ;
Modifiez la structure element_s afin quelle contienne un champ t_disque d
la place du champ int valeur ;
Adaptez les fonctions de cette bibliothque de faon approprie, aussi bien leur entte dans le fichier .h que leur corps dans le fichier .c.
Crez ensuite une nouvelle bibliothque guirlande, qui utilise disque.
TP 43

Algorithmique et programmation

2/4

disques & guirlandes

Exercice 9
Dans guirlande, crivez une fonction int genere_guirlande(liste_s* l, int
n), qui gnre alatoirement une liste de disques de longueur n, grce la fonction
genere_disque. La fonction doit renvoyer
en cas derreur et en cas de succs.
De plus, la fonction doit modifier la liste obtenue de manire la refermer : le dernier
lment de la liste doit pointer sur le premier lment (au lieu de pointer sur NULL).
exemple :
Une liste obtenue pour n=3, telle quelle est avant dtre referme :
{{432,235},19}

{{67,47},32}

{{15,47},27}

NULL

La mme liste, une fois quelle a t referme :

{{432,235},19}

{{67,47},32}

{{15,47},27}

Exercice 10
Dans guirlande, crivez une fonction void dessine_guirlande(liste_s l,
Uint32 coul), qui dessine chaque disque contenu dans la liste, en reliant les centres de
chaque paire de disques conscutifs par un segment. Les disques et les segments doivent tre
dessins dans la couleur passe en paramtre.
Remarque : vous devez placer le premier lment de la guirlande dans une variable
spcifique, afin de pouvoir dterminer quand vous avez fait le tour de toute la liste.
exemple : vous devez obtenir un affichage de la forme suivante, ici pour
disques :

Exercice 11
Dans guirlande, crivez une fonction void clignote_guirlande(liste_s l,
Uint32 coul1, Uint32 coul2, int k) qui fait clignoter la guirlande l. Un disque sur
deux doit tre dessin avec la couleur coul1, et lautre moiti avec coul2. Puis, la guirlande
doit tre redessine en inversant les couleurs, pour obtenir le clignotement. Les segments
doivent toujours rester de couleur coul1.
Le paramtre k indique le nombre de clignotements effectuer. L encore, utilisez
attends_delai pour contrler la vitesse de lanimation. Nutilisez pas un dlai trop petit,
pour viter les crises dpilepsie !
Remarque : on supposera que le nombre de disque dans la guirlande est pair.
exemple : guirlande de
disques, avec un clignotement alternant le rouge et le bleu :

TP 43

Algorithmique et programmation

3/4

disques & guirlandes

Exercice 12
Dans guirlande, crivez une fonction void anime_guirlande(liste_s l,
Uint32 coul, Uint32 couls[], int c, int k), qui reoit une guirlande l, une
couleur principale coul et un tableau de couleurs secondaires couls. Le paramtre c
reprsente la taille du tableau couls (i.e. le nombre de couleurs secondaires).
La fonction doit dabord dessiner la guirlande l en utilisant la couleur coul, qui est la
couleur principale. Puis, elle doit effectuer le traitement itratif suivant :
la premire itration, les disques sont coloris de la faon suivante :
o Disque numro en couls[0] ;
o Disque numro en couls[1] ;
o ...
o Disque numro
en couls[c-1] ;
o Disque numro et tous les disques suivants en coul.
la seconde itration :
o Disque numro : reprend la couleur principale coul ;
o Disque numro : couls[0] ;
o Disque numro : couls[1] ;
o ...
o Disque numro : couls[c-1] ;
o Le reste des disques (aprs le numro
) est colori avec coul.
On recommence jusqu avoir ralis k itrations.
Remarque : les segments entre les disques doivent toujours tre dessins en utilisant la
couleur coul.
exemple : premires itrations pour une guirlande de disques rouges, avec les couleurs
secondaires bleu, vert et jaune (dans cet ordre) :

TP 43

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 44

listes de caractres

Prsentation
On veut crer un programme qui ouvre un premier fichier texte, lit son contenu, passe les
minuscules en majuscules, et enregistre le rsultat dans un second fichier texte. Le texte sera
reprsent en mmoire sous la forme dune liste de caractres, et pour cette raison la
bibliothque liste_s est fournie avec le sujet.

1 Prparation
Exercice 1
Adaptez la bibliothque liste_s fournie avec le sujet, de manire ce quelle permettre
de traiter des listes de caractres et non pas des listes dentiers.

Exercice 2
crivez une fonction void convertis_liste(liste_s l) prenant une liste en
entre, et changeant chaque lettre minuscule par la lettre majuscule correspondante.
On peut remarquer que la fonction modifie la liste, et pourtant le paramtre est pass
directement (liste) et non pas travers un pointeur (liste*). Comment expliquez-vous
cette observation ?
Remarque : pensez utiliser la fonction initialise_liste_s pour tester votre
fonction.

2 Lecture
Exercice 3
crivez une fonction liste construis_liste(FILE *fp) reoit en paramtre un
fichier texte fp dj ouvert en lecture. La fonction doit lire le contenu de ce fichier en mode
caractre et construire une liste en utilisant la fonction insere_element. Vous devez
limplmentez sans utiliser aucune chane de caractres.
Considrez-vous cette approche comme efficace, notamment en termes de parcours de la
liste construite ? Justifiez.
Remarque : pour tester votre fonction, vous devez crer un fichier texte.txt placer dans
la racine de votre projet, dans lequel vous copiez-collez nimporte quel texte.

Exercice 4
Proposez une autre version plus efficace de construis_liste, que vous appellerez
construis_liste2. Vous ne devez toujours pas utiliser de chane de caractres, mais cette
fois vous ne devez pas utiliser insere_element non plus.
Expliquez en quoi cette version est plus efficace que la prcdente.

TP 44

Algorithmique et programmation

1/2

listes de caractres

3 criture
Exercice 5
crivez une fonction void ecris_liste(liste_s l, FILE *fp) qui reoit en
paramtre une liste de caractres l et un fichier fp dj ouvert en criture. La fonction doit
crire les caractres dans le fichier, en utilisant le mode caractre.

Exercice 6
crivez une fonction void copie_fichier(char *source, char *cible), qui cre le
fichier cible, qui est une copie du fichier source, en prcdant de la faon suivante :
Lire le fichier source et crer une liste de caractres reprsentant son contenu ;
Convertir ces caractres en majuscules ;
Enregistrer la liste obtenue dans le fichier cible.
Vous devez utiliser le plus possible les fonctions dj crites. Penser refermer les
fichiers, une fois que vous navez plus besoin dy lire ou dy crire.

TP 44

Algorithmique et programmation

2/2

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 45

tapis de Sierpiski

Prsentation
Dans ce TP, vous allez crire un programme qui trace des tapis de Sierpiski de faons
rcursive et itrative. Pour cela, vous utiliserez diffrentes bibliothques connues :
graphisme, qui permet de dessiner avec la SDL, et liste_s qui permet de manipuler des
listes simplement chanes. Vous devez donc configurer votre projet pour utiliser la SDL, puis
y copier les fichiers contenus dans larchive fournie avec ce sujet. Celle-ci comporte
galement un dossier exemples contenant des excutables montrant la construction de la
figure de faons rcursive et itrative.
Vous remarquerez que la bibliothque liste_s a t modifie pour manipuler des
valeurs de type point (et non pas des int). Ces points sont des structures dfinies par une
abscisse (x), une ordonne (y) et une couleur (coul). La fonction affiche_point permet
dafficher sous forme de texte les coordonnes du point p pass en paramtre. Cette fonction
ne sera pas utilise directement pour tracer la figure, mais elle vous sera utile pour tester vos
fonctions.

1 Dfinition
Le tapis de Sierpiski est une figure dfinie par le mathmaticien polonais Wacaw
Sierpiski en 1916.

tape 1
tape 2
tape 3
Cette figure peut se construire partir de diffrentes formes gomtriques. Pour simplifier
le traitement, nous utiliserons des carrs. La construction se dcompose en plusieurs tapes. A
la premire tape, un carr de ct et de centre est trac. A la deuxime tape, carrs de
ct sont tracs autour du carr initial. A la troisime tape, carrs de ct sont
tracs autour de chacun des carrs de la deuxime tape. Le traitement peut continuer ainsi
indfiniment.

2 Trac de carrs
Exercice 1
crivez une fonction trace_carre(point p, int cote) qui dessine un carr dont p
est le centre et cote est la longueur du ct (en pixels). Vous devez utiliser uniquement la

TP 45

Algorithmique et programmation

1/3

tapis de Sierpiski

fonction allume_pixel pour dessiner. De plus, les contours et lintrieur du carr doivent
tre de la mme couleur que p.

Exercice 2
En utilisant dessine_carre, crivez une fonction dessine_carres(liste_s l,
int cote) qui, pour chaque point p contenu dans la liste l, trace un carr de centre p et de
ct cote.

3 Version rcursive
La version rcursive consiste :
Dessiner le carr de centre et de cot ;
Calculer les centres des carrs qui lentourent ;
Recommencer le traitement pour chacun deux, avec un cot .
En thorie, on peut continuer le traitement linfini. Mais le carr le plus petit que lon
peut tracer sur lcran dun ordinateur est un pixel. Ceci constituera donc notre cas darrt.

Exercice 3
crivez une fonction int calcule_liste_centres(point p, int cote,
liste_s *l), qui reoit en paramtres un point p et une liste vide l. Elle doit calculer les
centres des carrs situs autour du carr de centre p et de ct cote, puis les placer ces
centres dans la liste. De plus, en cas derreur, la fonction renvoie

, et sinon elle renvoie .

Exercice 4
crivez une fonction int trace_sierpinski_rec(point p, int cote) qui
implmente rcursivement la construction dun tapis de Sierpiski. Le paramtre p
correspond au centre du premier carr de la figure, et cote est le ct de ce carr. Vous aurez
besoin des fonctions calcule_liste_centres et trace_carre. En cas derreur, la
fonction renvoie
, sinon elle renvoie .

4 Version itrative
Lalgorithme pour la version itrative repose sur lutilisation dune liste contenant tous les
points restant traiter. Pour chacun de ces points :
On trace le carr correspondant ;
On calcule les points qui lentourent ;
Ces points sont placs dans la liste qui servira pour litration suivante.
Lors de la premire itration il ny a quun seul point dans la liste, puis il y en a lors de
la deuxime itration,
lors de la troisime, etc. Ici aussi, la condition darrt porte sur la
dimension du ct des carrs.

Exercice 5
crivez une fonction int calcule_liste_tous_centres(liste_s *l1,
liste_s *l2, int cote). La liste l1 est une liste de points, et la liste l2 est une liste
vide. Les points de l1 sont tous des centres de carrs de mme ct cote. la fin du
traitement, la liste l2 doit contenir les centres de tous les carrs entourant ceux de l1. Pour
chaque point de l1, la fonction doit donc calculer les points qui lentourent, et les placer
dans l2. Pour cela, vous devez utiliser calcule_liste_centres. En cas derreur, la
fonction renvoie

, sinon elle renvoie .

Exercice 6
crivez une fonction int trace_sierpinski_it(point p, int cote) qui
implmente itrativement la construction dun tapis de Sierpiski. Le paramtre p correspond
au centre du premier carr de la figure, et cote est la dimension de ce carr. Vous aurez

TP 45

Algorithmique et programmation

2/3

tapis de Sierpiski

besoin des fonctions trace_carres et calcule_liste_tous_centres. En cas derreur,


la fonction renvoie
, sinon elle renvoie .

TP 45

Algorithmique et programmation

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 46

suite de Syracuse

Prsentation
Le but de ce TP est deffectuer diffrents calculs sur la suite de Syracuse, en manipulant
des listes doublement chanes. La bibliothque liste_d est donc fournie avec ce sujet.
La dernire partie consiste donner une reprsentation graphique de certains rsultats
obtenus, et pour cela nous utiliserons la SDL et la bibliothque graphisme. Cependant, ne
configurez pas encore votre projet pour lutilisation de la SDL, afin de pouvoir bnficier de
la sortie texte de votre programme. Lorsque la SDL sera ncessaire, cela sera indiqu dans
lnonc de lexercice concern, et vous pourrez alors configurer votre projet de faon
approprie.

1 Dfinition
On dfinit la suite de Syracuse de terme initial

), de la manire suivante :

Daprs la conjecture de Syracuse, quelle que soit la valeur initiale , il existe un rang
tel que
. partir de ce rang , la suite devient cyclique de cycle , , . Cette valeur
est appele temps darrt de la suite (pour le terme initial considr).
exemple : pour
, les termes de la suite sont :
,
,
,
,
,
,
,
,
, etc. Donc pour ce terme initial, on a
.
Remarque : une conjecture est une proprit qui na pas t dmontre, mais pour
laquelle on na jamais trouv de contre-exemple, et que lon suppose donc (temporairement)
vraie.

Exercice 1
Dans ce TP, nous aurons tout particulirement besoin dinsrer des lments en fin de
liste. crivez une fonction insere_element_fin_d qui insre un lment e la fin dune
liste doublement chane l, sans utiliser la fonction insere_element_d.

2 Implmentation itrative
Exercice 2
crivez une fonction itrative int calcule_syracuse_it1(int u0, liste_d
*l) qui prend en paramtre le terme initial u0 et une liste vide l, et qui remplit cette liste
avec les termes de la suite de Syracuse allant de
. La position dun terme dans la liste
doit correspondre sa position dans la suite. La fonction renvoie
en cas derreur et en
cas de succs.
exemple : pour u0=5, la fonction renvoie la liste 5,16,8,4,2,1.

Exercice 3
TP 46

Algorithmique et programmation

1/3

suite de Syracuse

Faites une copie de la fonction prcdente, renommez-la calcule_syracuse_it2, et


effectuez les modifications ncessaires pour quelle renvoie (en plus de la liste et du code
derreur) :
Le plus grand terme rencontr au cours du traitement ;
Le temps darrt, i.e. le rang du premier terme gal .
exemple : pour u0=5, en plus de la liste, la fonction renverra m=16 et j=5.

3 Implmentation rcursive
Exercice 4
crivez une fonction int calcule_syracuse_rec1(liste_d *l) qui effectue le
mme traitement que calcule_syracuse_it1, mais rcursivement. Contrairement
calcule_syracuse_it1, on supposera que la liste l nest pas vide. Donc le dernier terme
de la liste correspond au dernier terme de la suite ayant t calcul pour linstant. Par
exemple, si la liste contient les valeurs , , , alors on sait que le prochain terme calculer
est celui qui suit .
crivez aussi la fonction int calcule_syracuse_rec1_init(int u0, liste_d
*l) qui initialise la liste vide l avec le terme initial u0, puis utilise
calcule_syracuse_rec1 afin de lancer le traitement rcursif.

Exercice 5
Modifiez les deux fonctions de lexercice prcdent, de manire obtenir les fonctions
calcule_syracuse_rec2 et calcule_syracuse_rec2_init, capables de renvoyer

et .

4 Reprsentation graphique
Exercice 6
On sintresse maintenant la distribution du temps darrt par rapport aux termes de
dpart. crivez une fonction int vide_liste_d(liste_d *l) qui reoit une liste l
(suppose contenir des lments) et supprime tous ses lments en utilisant
supprime_element_d. La fonction renvoie
en cas derreur, et en cas de succs.

Exercice 7
crivez une fonction int calcule_temps(liste_d *l, int k) qui utilise lune
des fonctions calcule_syracuse pour calculer pour toutes les valeurs de
comprises
entre et . Autrement dit, on calcule pour
, puis pour
, puis
, etc.,
jusqu
.
Chacune de ces valeurs doit tre stocke dans la liste l passe en paramtre, qui est
initialement vide. Aprs lexcution de la fonction, le tout premier lment de la liste
correspond donc au temps darrt obtenu pour
, llment suivant au temps darrt
obtenu pour
, et ainsi de suite.
exemple : pour k=100, on obtient la liste suivante :
1 7 2 5 8 16 3 19 6
5 26 13 13 21 21 21
19 32 19 19 107 107
110 9 9 30 30 17 30

14 9 9 17 17 4 12 20 20 7 7 15 15 10 23 10 111 18 18 18 106
34 8 109 8 29 16 16 16 104 11 24 24 24 11 11 112 112 19 32
6 27 27 27 14 14 14 102 22 115 22 14 22 22 35 35 9 22 110
17 92 17 17 105 105 12 118 25 25 25

Remarque : pensez utiliser vide_liste_d pour supprimer la liste calcule par


calcule_syracuse (et non pas la liste rsultat de calcule_temps) chaque itration,
sinon vous allez progressivement remplir la mmoire, et provoquer une erreur dexcution
(que lon appelle une fuite de mmoire).

TP 46

Algorithmique et programmation

2/3

suite de Syracuse

Exercice 8
Finalement, configurez votre projet pour utiliser la SDL et la bibliothque graphisme.
Tracez un graphique reprsentant en abscisse les termes initiaux
et en ordonne les temps
darrt correspondant.
Pour simplifier le travail, on utilisera une chelle de
, i.e. un pixel dans le graphique
reprsente une diffrence de entre les
ou . Le graphique doit tre plac au centre de la
fentre graphique, la fois horizontalement et verticalement. Des traits doivent tre tracs sur
les axes toutes les
units (donc tous les
pixels, puisque lchelle est
).
exemple : pour les
premiers temps darrt, on obtient le graphique suivant :

Pour rfrence, le mme graphique donn pour les


la page Wikipedia).

TP 46

Algorithmique et programmation

premiers temps darrt (tir de

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 47

enveloppe d'un nuage de points

Prsentation
Ce TP porte sur le calcul denveloppes gomtriques, et leur trac grce la SDL. Vous
devez donc configurer votre projet de manire pouvoir utiliser la SDL. Vous avez galement
besoin de la bibliothque math, qui peut ncessiter une configuration spciale si vous
travaillez sous Linux.

1 Prparation
Le sujet est fourni avec une archive contenant les bibliothques graphisme et liste_dbl
dj utilises prcdemment.
noter que graphisme contient deux fonctions particulirement utiles pour ce TP :
void genere_point(int *x, int *y) : permet de gnrer alatoirement les
) dun point. Ces coordonnes sont, bien entendu, renvoyes par
coordonnes (
adresse.
void dessine_point(int x, int y, Uint32 coul) : permet de dessiner un
), sous la forme dune croix.
point de coordonnes (
La bibliothque liste_d contient galement une fonction ncessaire ce TP :
void trie_liste_decrois_d(liste *l) : permet de trier une liste dans lordre
dcroissant.
Dans la bibliothque math, vous aurez notamment besoin de la fonction suivante :
double acos(double a) : permet de calculer un angle (exprim en radians)
partir de son cosinus.

2 Dfinition
On dit quun polygone est crois sil possde au moins deux cts scants. Lenveloppe
quelconque dun nuage de points est un polygone non-crois dont les sommets sont les points
du nuage.

un nuage de points

un polygone crois
construit sur le nuage

une enveloppe du
nuage

une autre enveloppe du


mme nuage

Lobjectif de ce TP est de tracer lune des enveloppes possibles pour un nuage de points
gnr alatoirement.

TP 47

Algorithmique et programmation

1/4

enveloppe d'un nuage de points

3 Calcul de lenveloppe
Dterminer une enveloppe consiste trier les points afin dobtenir un chemin ferm, nonscant, et joignant chacun des points du nuage.
Algorithme :
1. Soit
le point le plus gauche de lcran (si plusieurs points sont sur la mme
colonne, est le point le plus haut).

2. Pour chaque point P du nuage de points, on calcule langle


dsigne un vecteur directeur de laxe horizontal. On a la proprit

), o
(
]

[.

3. On trie les points (sauf ) par dcroissants. Si deux points on le mme , on


considre que le plus haut est le plus grand. On obtient donc une liste ordonne des
).
points : (

5
7

4. On trace les cts du polygone (

).

5
7

TP 47

Algorithmique et programmation

2/4

enveloppe d'un nuage de points

4 Implmentation
Exercice 1
On veut reprsenter la liste de points en utilisant une liste chane. Un lment de cette
liste sera caractris par :
1. Des coordonnes x et y (exprimes en pixels)
2. Un angle (exprim en radians)
On ne va donc plus manipuler une liste dentiers basiques, comme ctait le cas
prcdemment (par exemple dans le TP sur les listes chanes).
Vous devez adapter la bibliothque liste_d aux nouvelles donnes :
Modifiez la structure de donnes element_d.
Modifiez les en-ttes des fonctions cree_element_d et affiche_liste_d dans
liste_d.h

Modifiez les corps des fonctions dans liste_d.c.

Exercice 2
Dans main.c, crivez une fonction int genere_nuage(int n, liste_d *l) qui cre
un nuage de points sous la forme dune liste de points gnrs alatoirement (en utilisant
genere_point). Les seront initialiss . La fonction renverra en cas de succs et
en
cas derreur.

Exercice 3
crivez une fonction trace_nuage(liste_d l , Uint32 coul) qui dessine les points
contenus dans la liste passe en paramtre, en utilisant la couleur coul. Pensez vous servir
de dessine_point.

Exercice 4
crivez une fonction element_d* extrais_P0(liste_d *l) qui :
1. Calcule quel est le point de la liste qui correspond ;
2. Enlve ce point de la liste, mais sans supprimer llment correspondant ;
3. Et renvoie un pointeur sur lelement_d correspondant .
Testez votre fonction en affichant dune autre couleur le point .
Attention :
Noubliez pas que la liste est doublement chane.
Nutilisez pas la fonction supprime_element_d, car elle dsallouera .

Exercice 5
crivez une fonction float calcule_angle(int v_x1, int v_y1, int v_x2, int

v_y2) qui calcule langle (


) exprim en radians, et ayant pour coordonnes
) et (
).
respectives (
Rappels :

Calcul du cosinus :
(
)
o | | reprsente la norme de .
| || |

Calcul du produit scalaire (dans une base orthonormale) :


Attention : langle obtenu nest pas orient (au sens trigonomtrique).

Exercice 6
crivez une fonction void calcule_theta(liste_d *l, element_d p0) qui calcule
(grce calcule_angle) le de chaque point , en fonction de . Noubliez pas dorienter
langle renvoy par calcule_angle, suivant la position de relativement
( est-il audessus ou au-dessous de ?).

TP 47

Algorithmique et programmation

3/4

enveloppe d'un nuage de points

Exercice 7
Dans liste_d.c, compltez la fonction int compare_elements_d(element_d e1,
element_d e2) dont le rle est de comparer deux lments e1 et e2, et de renvoyer un
entier positif si
, ngatif si
, ou nul sinon.
Remarque : la relation dordre entre les lments a t dcrite dans le principe de calcul
de lenveloppe.

Exercice 8
Dans main.c, crivez une fonction calcule_enveloppe(liste_d *l) qui ordonne la
liste l passe en paramtre, de manire obtenir son enveloppe. Vous utiliserez la fonction
trie_liste_decrois_d de la bibliothque liste_d.
Remarque : pensez rajouter dans la liste le point , qui avait t prcdemment retir.

Exercice 9
Dans main.c, crivez une fonction trace_polygone(liste_d l, Uint32 coul) qui
dessine le polygone (ferm) constitu des points contenus dans une liste l quelconque passe
en paramtre. Utilisez les fonctions attends_delai et rafraichis_fenetre de manire ce
que le polygone soit dessin progressivement (un ct la fois).

Exercice 10
Dans la fonction main, aprs avoir test chaque fonction sparment, ajoutez un
programme qui :
1. Initialise le nuage de points ;
2. Affiche ce nuage ;
3. Calcule son enveloppe ;
4. Affiche cette enveloppe sous la forme dun polygone ferm.

TP 47

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 48

marches de Graham & Jarvis

Prsentation
Ce TP est la suite directe du TP sur lenveloppe dun nuage de points. Il est bas sur
lutilisation de fonctions dveloppes au cours de ce TP. Par consquent, comme lui il
ncessite que votre projet soir configur de manire pouvoir utiliser la SDL et la
bibliothque math.
Le sujet est fourni avec une archive contenant les bibliothques graphisme et liste_d
dj utilises prcdemment, ainsi que la bibliothque enveloppe, qui contient les fonctions
du TP sur lenveloppe dun nuage de points.

1 Dfinitions
Un polygone est dit convexe si toutes ses diagonales se trouvent lintrieur du polygone.
Sil existe au moins une diagonale qui nest pas entirement incluse dans le polygone, on dit
que le polygone possde une concavit. Dans ce cas l, le polygone est non-convexe.

polygone convexe

polygone non-convexe

concavit

Lors du TP sur lenveloppe dun nuage de points, nous avons calcul lenveloppe
quelconque dun nuage de points. Cette enveloppe correspond un polygone, qui est en
gnral non-convexe.
Lenveloppe convexe dun nuage de points est le plus petit (pour la relation dinclusion)
polygone convexe contenant tous les points du nuage.

un nuage de points

une enveloppe nonconvexe du nuage

lenveloppe convexe du
nuage

Lobjectif de ce TP est de calculer lenveloppe convexe dun nuage de points partir


dune enveloppe quelconque.

TP 48

Algorithmique et programmation

1/5

marches de Graham & Jarvis

2 Marche de Graham
2.1 Principe
Cet algorithme permet dobtenir lenveloppe convexe en supprimant toutes les concavits
prsentes dans une enveloppe quelconque. Nous prendrons comme point de dpart une liste
de points ordonns de manire constituer une enveloppe quelconque (cf. le TP sur
lenveloppe dun nuage de points).
Pour un point , on peut remarquer la proprit suivante :
) appartient
Si
correspond une concavit, alors langle (
]

[.

) appartient ]
Sinon, langle (
P1

[.
P1

P2

P3

P0

P2

P0
P4

P4

P5
P7

P3

P5
P7

P6
point normal

P6
concavit

En calculant le dterminant des deux vecteurs, on peut donc facilement dtecter les
concavits :

[ ( )
]
[( ) ]
[] : le point
est
lintrieur de lenveloppe convexe.
) ]
[] : le point est un sommet
[ ( )
]
[(
de lenveloppe convexe.
Algorithme :
) la liste ordonne des points, formant une enveloppe
Soit (
quelconque.
Pour chaque (
):
o Si le dterminant est ngatif ou nul :

est supprim de la liste.


Si le point prcdant est , on passe
.
Sinon on teste nouveau ce point prcdent.
o Sinon : est conserv, on passe
(le point suivant).
la fin du traitement, les points restants dans la liste sont les sommets de
lenveloppe convexe.

TP 48

Algorithmique et programmation

2/5

marches de Graham & Jarvis

3
5

4
7

application de lalgorithme

Remarque : pour

enveloppe convexe obtenue

, on considrera le couple de vecteurs ( ).

2.2 Implmentation
Exercice 1
crivez une fonction float calcule_determinant(int v_x1, int v_y1, int v_x2,
int v_y2) qui calcule le dterminant du couple de vecteurs ( ), et ayant pour
) et (
)
coordonnes respectives (

Exercice 2
crivez une fonction void marche_graham(liste_d *l) qui calcule lenveloppe
convexe du nuage de points reprsent par la liste l. Cette liste est suppose ordonne de
manire correspondre une enveloppe quelconque. Vous supprimerez les lments de l en
appliquant lalgorithme de Graham.

3 Marche de Jarvis
3.1 Principe
la diffrence de la marche de Graham, la marche de Jarvis ne ncessite pas une liste
ordonne des points. Elle repose sur la proprit suivante :
Considrons deux points
et
appartenant lenveloppe convexe, tels que si on
parcourt cette enveloppe dans le sens ngatif, est situ juste aprs
. Alors
(le point
) est maximal.
suivant dans lenveloppe) est le point du nuage tel que langle (

En dautres termes : quand on connat un ct de lenveloppe convexe, il est possible de


dterminer le point suivant.
Algorithme :
Initialisation :
o Soit
le point le plus gauche et en haut de lcran (comme
prcdemment).
o On note
le point suivant de lenveloppe convexe. Pour le calculer, on
aurait besoin de connatre le ct prcdent, mais ce nest pas le cas. On

TP 48

Algorithmique et programmation

3/5

marches de Graham & Jarvis

utilise la place le vecteur

(aucun point ne peut tre gauche de


) est maximal.
est alors le point tel que langle
(

).

Cas gnral : (le point suivant dans lenveloppe convexe) est le point tel que
) est maximal. Si plusieurs points ont un angle maximal
langle
(
(i.e. ces points sont aligns avec ), on retient celui qui est le plus loign de

En appliquant itrativement ce traitement jusqu retomber sur , on construit


lenveloppe convexe.

3.2 Implmentation
Exercice 3
crivez une fonction void calcule_gamma(liste_d *l, element_d p1, element_d
p2) qui reoit une liste de points et deux points de rfrence
et . La fonction doit mettre
jour le champ angle de chaque lment de la liste, de manire ce quil contienne la

).
valeur
(

Exercice 4
crivez une fonction element_d* extrais_suivant(liste_d *l, element_d p2) qui
reoit une liste dlments, et dtermine quel est le point (parmi ceux de la liste) suivant dans
lenveloppe, i.e. celui qui a le
maximal (les
ayant dj t calculs grce
calcule_gamma). Il faut galement extraire ce point de la liste (sans supprimer llment
correspondant, bien entendu), et renvoyer son adresse.
Remarques :
Inspirez-vous de la fonction extrait_P0 crite prcdemment.
Le paramtre p2 est utile en cas dgalit.

Exercice 5
TP 48

Algorithmique et programmation

4/5

marches de Graham & Jarvis

crivez une fonction element_d* clone_element(element_d e) qui construit un clone


de llment e pass en paramtre. Un clone est un nouvel lment contenant les mmes
valeurs x, y, angle, precedent et suivant que e. Le clone est renvoy par adresse.

Exercice 6
crivez une fonction liste_d marche_jarvis(liste_d *l) qui calcule lenveloppe
convexe du nuage de points reprsent par la liste l. Dans cette fonction, vous manipulerez
deux listes :
La liste l2 des points qui appartiennent lenveloppe convexe, que vous
initialiserez avec et .
La liste l des autres points, qui nappartiennent pas (encore) lenveloppe
convexe.
La liste l2 sera construite itrativement en appliquant la marche de Jarvis.
Remarque : le point
doit tre la fois dans l2 (puisquil fait partie de lenveloppe
convexe) et dans l (puisquil est utilis dans la condition darrt de lalgorithme). Il est
impossible que le mme lment appartienne deux listes la fois, vous devrez donc cloner
llment reprsentant .

TP 48

Algorithmique et programmation

5/5

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 49

analyse dexpressions

Prsentation
Le but de ce TP est de manipuler les piles de donnes vues en cours. Pour cela, on
sintressera lanalyse dexpressions reprsentant des calculs arithmtiques simples.

1 Notation polonaise inverse


La notation la plus rpandue pour crire une expression arithmtique est la notation
infixe : un oprateur binaire est plac entre ses deux oprandes :
. Cette notation
ncessite parfois lutilisation de parenthses pour exprimer certains calculs, comme par
) (
).
exemple : (
Il existe galement des notations dites prfixes et postfixes. Avec une notation prfixe,
loprateur prcde ses oprandes (
) alors quil leur succde si on utilise une notation
postfixe (
).
La notation polonaise est une notation prfixe propose par le mathmaticien polonais
Jan ukasiewicz en 1920. Dans cette notation, chaque oprateur possde une arit bien
dfinie : il nexiste pas doprateurs homonymes. Par exemple, loprateur soustraction
(binaire) nest pas reprsent par le mme signe que loprateur ngation (unaire). La notation
polonaise offre la particularit de ne pas ncessiter de parenthses : lexpression infixe
(
) (
) devient :
.
La notation polonaise inverse (NPI) est une version postfixe de la notation polonaise.
Lavantage sur la notation polonaise est que lalgorithme qui permet dvaluer des
expressions NPI est plus simple. Cest pour cette raison que les premires calculatrices
lectroniques (dans les annes 60) utilisaient cette notation. Avec la NPI, lexpression
prcdente prend la forme suivante :
.

2 Mthode dvaluation
Pour valuer une expression crite en NPI, on utilise une pile de donnes et on parcourt
lexpression en partant de la gauche et en traitant chaque signe. Ici, le mot signe dsigne un
lment quelconque de lexpression, c'est--dire un oprande ou un oprateur.
Tant quil reste des signes dans lexpression :
o Si le signe est un oprande :
Il est empil.
o Si le signe est un oprateur :
On dpile un nombre doprandes correspondant son arit ;
On applique loprateur ces oprandes ;
Le rsultat est empil.
Sil ne reste plus de signe dans lexpression, alors le sommet de la pile correspond
au rsultat de lvaluation.
exemple : valuation de lexpression

TP 49

Algorithmique et programmation

1
1/4

analyse dexpressions

o On empile 1.
:
o On empile 2.
:
o On dpile deux oprandes : 2 et 1.
o On calcule
.
o On empile le rsultat 3.
:
o On empile 3.
:
o On empile 4.
:
o On dpile deux oprandes : 4 et 3.
o On calcule
.
o On empile le rsultat 7.
:
o On dpile deux oprandes : 7 et 3.
o On calcule
.
o On empile le rsultat 21.
:
o Il ny a plus de signe dans lexpression.
o Le rsultat est le sommet : 21.

1 2
1 2
3
3 3
3 3 4
3 3 4
3 7
3 7
21

3 Implmentation de la mthode
Nous manipulerons exclusivement des oprandes entiers. Lexpression valuer sera
reprsente par une chaine de caractres pouvant contenir les caractres suivants :
Les oprateurs :
o '+' (addition).
o '' (soustraction).
o '*' (multiplication).
o '/' (division entire).
o '%' (reste de la division entire).
Les chiffres de '0' '9'.
Le caractre espace ' '.
Le caractre espace est utilis seulement pour sparer deux oprandes qui ne sont pas dj
spars par un oprateur. Le caractre espace ne doit apparatre que dans ce cas bien prcis.
En particulier, les oprandes et les oprateurs ne sont pas spars par un espace.
exemples : lexpression
:
est reprsente par la chane "1 2+3 4+*".
nest pas reprsente par la chane "1 2 + 3 4 + *".
Larchive fournie avec ce sujet contient une bibliothque pile_liste correspondant
limplmentation du type abstrait pile au moyen dune liste. La bibliothque contient
galement les fonctions de manipulation des piles vue en cours. Larchive contient aussi la
bibliothque liste_s (liste simplement chane), qui est utilise par pile_liste.

Exercice 1

TP 49

Algorithmique et programmation

2/4

analyse dexpressions

crivez une fonction int est_operateur(char c) qui reoit un caractre c. La fonction


doit renvoyer si le caractre pass en paramtre est un oprateur, ou sinon.
exemples :
Pour c='1', la fonction doit renvoyer .
Pour c=' ', la fonction doit renvoyer .
Pour c='*', la fonction doit renvoyer .

Exercice 2
crivez une fonction similaire int est_chiffre(char c) qui reoit un caractre et
dtermine si le caractre est un chiffre.

Exercice 3
crivez une fonction int calcule_entier(char *exp, int *pos) qui reoit
lexpression exp et le numro pos dun de ses caractres. La fonction doit calculer la valeur
du nombre entier dont les chiffres sont compris entre le caractre numro pos (inclus) et le
prochain caractre qui ne soit pas un chiffre. Elle doit modifier pos de manire ce quil
indique ce caractre de sparation. Enfin, elle doit renvoyer la valeur de lentier.
Remarque : on suppose que le caractre initialement indiqu est un chiffre.
exemples : la fonction reoit lexpression suivante :
0

9 9 4

9 10 11 12 13 14 15 16 17

3 2 4 + 5 4 2 + 3

4 + * \0

Pour *pos=0 : le rsultat est 994 et *pos a la valeur 3 la fin du traitement.


Pour *pos=8 : le rsultat est 542 et *pos prend la valeur 11.
Pour *pos=14 : le rsultat est 4 et *pos prend la valeur 15.

Exercice 4
crivez une fonction int applique_operateur(char opt, int opd1, int opd2) qui
renvoie le rsultat du calcul consistant appliquer loprateur reprsent par le caractre opt
aux deux oprandes opd1 et opd2 passs en paramtres.
Remarque : on suppose que le caractre opt reprsente bien un oprateur.
exemple : applique_operateur('+',2,3) doit renvoyer la valeur 5.

Exercice 5
En utilisant les fonctions prcdentes et les fonctions de manipulation de piles, crivez
une fonction int evalue_NPI(char *expression, int *resultat) qui value une
expression crite en NPI. Vous appliquerez lalgorithme dcrit plus haut.
Le rsultat de lvaluation sera renvoy par adresse via le paramtre resultat. En cas
derreur, la fonction doit renvoyer
par valeur. En cas de succs, elle renvoie . Une erreur
se produit quand lexpression passe en paramtre ne respecte pas les rgles dcrites
prcdemment.

4 Gestion des erreurs


Exercice 6
crivez une fonction void interface_NPI() qui :
Demande lutilisateur de saisir une expression
value lexpression
o En cas de succs : la fonction affiche le rsultat.
o En cas derreur : la fonction affiche un message derreur.
exemples :
TP 49

Algorithmique et programmation

3/4

analyse dexpressions

Une expression correcte :

Entrez lexpression NPI a evaluer : 1 2+3 4+*


Le resultat est : 21.

Une expression incorrecte :

Entrez lexpression NPI a evaluer : 1 2 +


Erreur lors de l'evaluation.

Exercice 7
Le message derreur de la fonction prcdente est imprcis, ce qui rend difficile la
correction de lventuelle erreur dtecte dans une expression. Faites une copie de
evalue_NPI que vous appellerez evalue_NPI_2, et modifiez-la pour quelle renvoie
diffrents codes derreur :
La chane reprsentant lexpression est vide :
La chane contient un caractre interdit :
La chane contient un espace mal plac :
Il manque un oprateur dans la chaine :
Il manque un oprande dans la chaine :
Une autre erreur survient (par exemple : erreur daccs mmoire dans une fonction
de la pile) :
Il ny a pas derreur :
Ces diffrentes valeurs doivent tre dfinies sous formes de constantes.

Exercice 8
Faites une copie de interface_NPI que vous appellerez interface_NPI_2 et modifiez-la
de manire lui faire afficher un message diffrent pour chaque code derreur possible.
exemple :
Entrez lexpression NPI a evaluer : 1 2+3 4+
Erreur : un operateur est manquant.

Exercice 9
Faites des copies des fonctions evalue_NPI_2 et interface_NPI_2 que vous appellerez
respectivement evalue_NPI_3 et interface_NPI_3. Modifiez-les de manire faire
apparatre la position du caractre de la chane qui a provoqu lerreur dtecte.
exemple :
Entrez lexpression NPI a evaluer : 1 2 +
Erreur : un espace est mal place (pos.3).

Exercice 10
crivez une fonction void souligne_erreur(char *expression, int position) qui
affiche lexpression en la soulignant jusqu la position passe en paramtre.
exemple : pour lexpression et la position de lerreur de lexemple prcdent
1 2 +
^^^^

Exercice 11
Faites une copie de la fonction interface_NPI_3 que vous appellerez interface_NPI_4,
et modifiez-la de manire lui faire afficher lexpression souligne en cas derreur.
exemple :
Entrez lexpression NPI a evaluer : 1 2+3 4+
Erreur : un operateur est manquant (pos.8).
1 2+3 4+
^^^^^^^^^

TP 49

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 50

conversion dexpressions

Prsentation
Ce sujet fait suite au TP sur le traitement dexpressions mathmatiques crites en notation
polonaise inverse (NPI). Le but est dapprofondir lutilisation des piles de donnes ainsi que
de la rcursivit.
La bibliothque npi fournie avec ce sujet contient limplmentation des principales
fonctions du TP prcdent, utiliser dans ce TP. Les fonctions que vous crirez au cours de ce
TP doivent constituer une nouvelle bibliothque infixe, qui utilise elle-mme npi. Comme
dhabitude, chaque fonction doit tre teste dans la fonction main du fichier principal
main.c.

1 Expression infixes
Nous avons vu dans ce TP que la NPI offre lavantage de faciliter lvaluation des
expressions. Par contre, la NPI ne parait pas trs pratique pour une personne habitue la
notation infixe.
Pour bnficier des avantages propres chaque notation, nous allons dfinir des fonctions
permettant de convertir une expression infixe en NPI. Afin de simplifier la conversion, nous
allons faire des hypothses quant la forme des expressions infixes traiter :
Elles contiennent seulement des caractres reprsentant :
o Des chiffres.
o Des parenthses.
o Les oprateurs entiers binaires '+', '-', '*', '/' et '%'.
Elles sont compltement parenthses :
o Tout triplet
constitu dun oprateur et de ses oprandes
et
).
est entour dune paire de parenthses : (
o Les parenthses ne doivent apparatre qu cette seule occasion.
exemples :
Expressions compltement parenthses :
o
o

(1+3)
(2-((1+3)+5))

Expressions pas compltement parenthses :


o
o
o
o
o

1+3+5
(1+3)+5
1+3
(1)
2-1+3

2 Parenthsage
La premire tape consiste tester si lexpression infixe traiter est bien compltement
parenthse. On peut utiliser pour cela le principe rcursif suivant :

TP 50

Algorithmique et programmation

1/4

conversion dexpressions

(
)
Une expression exp est compltement parenthse si et seulement si
avec :
Loprande op1 est soit une expression compltement parenthse, soit un entier.
Loprateur est lun des oprateurs autoriss.
Loprande op2 est soit une expression compltement parenthse, soit un entier.

Exercice 1
Dans infixe, crivez une fonction void passe_entier(char *exp, int *pos)
qui prend en paramtres une expression exp et le numro pos dun caractre de cette
expression. Le caractre exp[*pos] est le premier chiffre dun nombre de lexpression. La
fonction doit modifier *pos de manire ce que exp[*pos] soit le premier caractre suivant
ce nombre.
exemple : pour exp="((12+3456)*78)" et *pos=5
avant dappliquer la fonction : *pos=5
(

aprs avoir appliqu la fonction : *pos=9


8

Exercice 2
En utilisant le principe rcursif propos ci-dessus, crivez dans infixe une fonction int
est_correcte_rec(char *exp, int *pos) qui teste si lexpression infixe exp est
correcte. Le pointeur pos reprsente le numro du prochain caractre traiter, par consquent
il devra pointer sur une variable contenant la valeur lors de lappel initial. La fonction doit
vrifier la fois que lexpression est correctement parenthse, et quelle ne contient que des
caractres autoriss. Elle renvoie si lexpression est correcte, et sinon.
exemples :
Pour lexpression (1+3), la fonction renvoie et donne pos la valeur .
Pour lexpression 1+3, la fonction renvoie
(et la valeur de pos na plus
dimportance)

Exercice 3
On peut remarquer que le principe rcursif prsent ne traite pas le cas "(0+(1+2))+3"
car la vrification de lexpression est arrte aprs la dernire parenthse fermante. crivez
dans infixe une fonction int
est_correcte(char
*exp) qui utilise
est_correcte_rec pour vrifier lexpression, puis qui traite ce cas particulier. La fonction
renvoie si lexpression est correcte, et sinon.
exemples :
Pour lexpression (0+(1+2))+3, la fonction renvoie ;
Pour lexpression ((0+(1+2))+3), la fonction renvoie .

3 Conversion & valuation


Exercice 4
Pour convertir une expression infixe en NPI, on utilise une pile de donnes et on parcourt
lexpression en partant de la gauche.
Tant quil reste des caractres dans lexpression :
o Si le caractre est un chiffre : il est copi la fin de la chane rsultat.
o Si le caractre est un oprateur :
Il est empil.
Si le dernier caractre copi dans la chane rsultat est un chiffre :
un caractre espace ' ' est plac la fin de la chane rsultat.

TP 50

Algorithmique et programmation

2/4

conversion dexpressions

o Si le caractre est une parenthse ouvrante '(' : on passe simplement au


caractre suivant.
o Si le caractre est une parenthse fermante ')' : loprateur situ au
sommet de la pile est dpil et copi la fin de la chane rsultat.
Remarque : lutilisation des caractres espace ' ' dans lexpression obtenue doit
respecter les contraintes dfinies dans le TP sur les NPI.
exemple : conversion de "(1+((2*3)+4))"
infixe (

infixe (

NPI

NPI

pile

pile

infixe (

infixe (
NPI

pile
infixe (

NPI

pile

infixe (

NPI

pile

pile

infixe (

NPI

pile

pile

infixe (

NPI

NPI

pile

pile

infixe (
NPI

pile

infixe (
NPI

pile

infixe (
NPI

NPI

infixe (

+
2

NPI

infixe (

pile
1

2
*

Dans infixe, crivez une fonction int convertis_infixe_vers_npi(char


*exp1, char *exp2) qui convertit une expression infixe exp1 en une expression NPI
exp2. La fonction renvoie en cas de succs et
en cas derreur.
exemple : lexpression "(1+((2*3)+4))" devient "1 2 3*4++".

Exercice 5
Dans infixe, crivez une fonction int evalue_infixe(char *expression, int
*resultat, int *position) qui reoit une expression infixe et lvalue. Le rsultat est

TP 50

Algorithmique et programmation

3/4

conversion dexpressions

renvoy par adresse via le paramtre resultat. La fonction doit raliser les oprations
suivantes :
Tester si lexpression infixe reue est compltement parenthse ;
La convertir en une expression NPI ;
valuer cette nouvelle expression.
exemple : pour lexpression "(1+((2*3)+4))", la fonction renvoie .
Le paramtre position sert renvoyer la position de lerreur, le cas chant. De plus, la
fonction doit renvoyer en cas de succs et un code spcifique en cas derreur :

si lexpression originale nest pas compltement parenthse ;

si un problme se produit lors de la conversion


Autrement : le code derreur renvoy lors de lvaluation de lexpression NPI.
Remarque : dfinissez des constantes pour reprsenter les codes derreur.

Exercice 6
Dans infixe, copiez la fonction void interface_npi() de la bibliothque npi, et
renommez-la en void interface_infixe(). Modifiez cette fonction de manire ce
quelle value des expressions infixes, et affiche les messages derreur correspondants.
exemples :
Une expression correcte :
Entrez l'expression infixe a evaluer : (1+((2*3)+4))
Le resultat est : 11.

Une expression qui nest pas compltement parenthse :

Entrez l'expression infixe a evaluer : (1+((2*3)+4)


Erreur : l'expression n'est pas completement parenthesee.

TP 50

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 51

dtection de palindromes

Prsentation
Le but de ce TP est dapprofondir des notions dj tudies en cours et lors des TP
prcdents, en particulier : chanes de caractres, pointeurs, allocation dynamique, fonctions
rcursives, piles de donnes.

1 Notion de palindrome
Un palindrome est un mot symtrique, c'est--dire que lon peut le lire dans les deux sens
(en partant du dbut ou de la fin). Exemples de mots constituants des palindromes : rotor,
kayak, radar, selles, t Ce TP porte sur limplmentation de diffrents algorithmes
permettant de dterminer si une chane de caractres donne est un palindrome.

2 Par renversement
Exercice 1
crivez une fonction inverse_chaine(char *chaine) qui reoit en paramtre un
pointeur sur une chane de caractres chaine et construit une nouvelle chane correspondant
linverse de chaine. Lespace mmoire occup par cette nouvelle variable doit tre minimal.
La fonction doit renvoyer un pointeur vers la nouvelle chane, ou la valeur NULL en cas
derreur.
exemple : applique une chane "abcd", la fonction doit renvoyer un pointeur sur une
chane "dcba".

Exercice 2
crivez une fonction rcursive compare_chaines(char *chaine1, char *chaine2)
qui compare caractre par caractre les deux chanes passes en paramtres. La fonction
renvoie si les deux chanes sont identiques et sinon.
exemples :
Lappel compare_chaines("abcd","abce") renvoie ;
Lappel compare_chaines("abcd","abcd") renvoie .

Exercice 3
En utilisant les fonctions inverse_chaine et compare_chaines, crivez une fonction int
est_palindrome1(char *chaine) qui dtermine si une chane de caractres est un
palindrome : elle doit renvoyer si la chane est un palindrome, et sinon.
exemples :
Lappel est_palindrome1("abcd","eizyuepzep") renvoie ;
Lappel est_palindrome1("abcd","dcba") renvoie .

TP 51

Algorithmique et programmation

1/4

dtection de palindromes

3 Par double parcours


Un autre algorithme pour dterminer si une chane de caractres est un palindrome
consiste comparer les caractres en partant des deux extrmits (le dbut et la fin) et en se
dplaant vers le centre :
On continue se dplacer vers le centre tant que les caractres sont gaux.
On sarrte quand on arrive au centre (cest un palindrome) ou quand les deux
caractres compars ne sont pas gaux (ce nest pas un palindrome).
exemples : on considre successivement les chanes "kayak", "selles" et "abaca" :
=

1)

k a y a k

1)

2)
3)

k a y a k
vrai
k a y a k

s e l l e s

1)

2)

s e l l e s

a b a c a

2)

a b a c a

3)
4)

s e l l e s

3)

faux

vrai
s e l l e s

Exercice 4
crivez une fonction itrative int est_palindrome2_it(char *chaine) qui prend une
chane de caractres en paramtre et implmente lalgorithme du double parcours pour
dterminer sil sagit dun palindrome. La fonction renvoie si le mot est un palindrome et
sinon.

Exercice 5
Exprimez lalgorithme prcdent sous forme rcursive, en prcisant les ventuels cas
darrt, cas derreur et cas gnral (ou cas gnraux).
crivez ensuite la fonction rcursive int est_palindrome2_rec_sec(char *debut,
char *fin) qui implmente cet algorithme. Les paramtres debut et fin pointent
respectivement sur le premier et le dernier caractres de la chane traiter.

Exercice 6
Enfin, crivez la fonction int est_palindrome2_rec(char *chaine), qui initialise les
paramtres debut et fin, puis effectue le premier appel de la fonction
est_palindrome2_rec_sec.

4 Par empilement
Le dernier algorithme utilise une pile de caractres pour effectuer lanalyse. Pour ces
exercices, vous disposez de la bibliothque pile_liste dfinie en cours et utilise en TP.
Elle a t adapte pour pouvoir traiter des piles de valeurs de type char.
La premire tape de lalgorithme consiste empiler le contenu de la chane dans la pile,
caractre par caractre. La deuxime tape consiste comparer la chane avec le contenu de la
pile, caractre par caractre. On considre le premier caractre de la chane et le sommet de la
pile :
Sils sont diffrents, alors la chane nest pas un palindrome.
Sinon, on dpile et on recommence avec le caractre suivant dans la chane.

TP 51

Algorithmique et programmation

2/4

dtection de palindromes

Si la pile est vide, cest quil sagit dun palindrome.


=

pile

a b a c a

1)

a
c
a
b
a

a b a c a

a b a c a
c
a
b
a

2)

3)

Exercice 7
crivez une fonction int initialise_pile(char *chaine, pile *p) qui reoit un
pointeur sur une pile vide et y recopie les caractres composant la chane reue en paramtre.
La fonction renvoie la valeur
si une erreur se produit, et sinon.

Exercice 8
En utilisant la fonction initialise_pile et lalgorithme prsent ci-dessus, crivez une
fonction int est_palindrome3(char *chaine) qui dtermine si une chane de caractres
est un palindrome. La fonction renvoie les mmes valeurs que les autres fonctions
est_palindromex.

5 Gnralisation
On peut gnraliser la notion de palindrome une phrase. Dans ce cas-l, on ignore
gnralement la ponctuation, les accents et les espaces, par exemple : "lu par cette crapule
!", "Engage le jeu, que je le gagne.", "La mre Gide digre mal."

Exercice 9
On veut utiliser les fonctions prcdentes pour traiter ces palindromes. Pour cela, il suffit
de nettoyer les chaines de caractres, de manire ne garder que les lettres. De plus, les lettres
majuscules doivent tre transformes en minuscules. On veut effectuer ce traitement en
modifiant directement la chaine concerne (i.e. sans passer par un autre tableau).
exemple : sur la phrase "A ba'ca" (phrase qui na aucune signification)
ecriture

ecriture
A

1)

b a ' c a \0

lecture

lecture

ecriture

ecriture
a

2)

a b a a ' c a \0

5)

b a ' c a \0

a b a a ' c a \0

6)

lecture

lecture

ecriture

ecriture
a

3)

b a ' c a \0

a b a c ' c a \0

7)

lecture

lecture

ecriture

ecriture
a b b a ' c a \0

4)

a b a c a c a \0

8)

lecture

lecture

9)

TP 51

Algorithmique et programmation

a b a c a \0 a \0

3/4

dtection de palindromes

crivez une fonction rcursive void nettoie_chaine(char *lecture, char


*ecriture) qui effectue le nettoyage dcrit ci-dessus. Le pointeur lecture indique quel est
le prochain caractre traiter, le pointeur ecriture indique quel endroit le prochain
caractre devra tre recopi.

Exercice 10
crivez une fonction int est_palindrome_phrase(char *phrase) qui teste si la
phrase passe en paramtre est un palindrome, en utilisant les fonctions des exercices
prcdents.
exemple : pour la phrase "Engage le jeu, que je le gagne !", la fonction doit renvoyer la
valeur .
Remarque : par souci de simplification, on supposera que la phrase ne contient pas de
caractres accentus.

TP 51

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 52

tours de Hano

Prsentation
Ce TP repose sur la SDL, donc votre projet doit tre configur de manire pouvoir
lutiliser. Larchive fournie avec ce sujet contient la bibliothque pile_tab crite en cours,
qui implmente le type abstrait pile pour les entiers.
Larchive inclut galement la bibliothque graphisme, qui permet de dessiner grce la
SDL. En plus des fonctions habituelles, vous y trouverez une fonction
remplis_rectangle(int x, int y, int l, int h, Uint32 coul) qui permet de
dessiner un rectangle plein :
abscisse x
ordonne y

couleur coul
hauteur h
largeur l

1 Description
Le problme des tours de Hano est un jeu de rflexion publi par le mathmaticien
douard Lucas en 1883. Lunivers du problme se compose de axes verticaux et dun
ensemble de
disques de diamtres diffrents, et percs en leur centre. Au dbut du
problme, tous les disques sont empils sur laxe de gauche. Le but du jeu est de dplacer la
pile sur laxe de droite en un minimum dactions.
disques

axes

1
2
3
4

dbut du jeu
sommet

1
2
3
4

fin du jeu
Le dplacement des disques est soumis aux rgles suivantes :
On ne peut dplacer quun seul disque la fois.
On ne peut prendre un disque sur une pile que sil se trouve au sommet de cette
pile.
On ne peut poser un disque sur une pile que si le disque qui est au sommet de cette
pile est dun diamtre suprieur.
De plus, on fait lhypothse quau dbut du jeu, les disques sont disposs de manire
respecter ces rgles.

TP 52

Algorithmique et programmation

1/4

tours de Hano

2 Implmentation
Nous allons utiliser la structure de donnes des piles pour reprsenter les empilements de
disques manipuls dans le problme des tours de Hano. Chaque disque sera reprsent par un
entier correspondant son numro. Un disque sera dplac en effectuant des actions
empiler/dpiler.
Diffrentes constantes sont dfinies dans le fichier main.c afin de faciliter la manipulation
des disques :
N : nombre de disques du problme.
AXE_LARGEUR, AXE_HAUTEUR : largeur et hauteur des axes exprimes en pixels.
DISQUE_LARGEUR_MIN : largeur du plus petit disque exprime en pixels.
DISQUE_LARGEUR_COEF : valeur utilise pour calculer la largeur dun disque.
DISQUE_HAUTEUR : hauteur des disques exprime en pixels.

Exercice 1
Dans le fichier main.c, crez un type numr position qui permettra de reprsenter la
position dun axe. Ce type contient symboles : gauche < centre < droite.

Exercice 2
Crez un type structure axe qui nous servira reprsenter un des trois axes du problme.
Chaque axe est caractris par :
Sa position ;
Ses disques (reprsents par une pile dentiers).

Exercice 3
crivez une fonction int initialise_probleme(axe *a_g, axe *a_c, axe *a_d),
qui initialise les axes gauche a_g, central a_c et droit a_d. La fonction renvoie en cas de
succs ou
en cas derreur.

Exercice 4
crivez une fonction Uint32 quelle_couleur(int disque) qui prend en paramtre le
numro dun disque disque (<N), et renvoie une constante correspondant une couleur SDL.
Chaque disque doit avoir une couleur diffrente.

Exercice 5
En utilisant seulement les fonctions du type abstrait pour accder la pile, crivez une
fonction trace_axe(axe a, int x, int y), qui dessine un axe et ses disques. La
coordonne x correspond au centre de laxe, et y correspond au ct suprieur de laxe. La
largeur du disque numro est gale DISQUE_LARGEUR_MIN
DISQUE_LARGEUR_COEF.
x
y
axe

1
TP 52

Algorithmique et programmation

disque 1

2/4

tours de Hano

Exercice 6
crivez une fonction trace_probleme(axe a, axe b, axe c), qui dessine les axes et
les disques. Attention, a nest pas forcment laxe gauche, ni b et c les axes central et droit.
Vous devez utiliser le champ indiquant la position de chaque axe, pour savoir o le placer.
axe gauche

axe droit

1
2
3
4

axe central

Remarque : les trois axes doivent tre bien rpartis gauche, au milieu et droite de
lcran.

3 Rsolution
Il est possible de montrer que le problme des tours de Hano admet une solution quel que
soit le nombre de disques utiliss.
Proprit
: il est possible de dplacer une pile de disques dun axe vers
un axe (en respectant videmment les rgles de dplacement).
exemple 1

1
2
3
A
exemple 2

1
2
3

1
2
3
A

1
2
3

4
B

Cas de base :
: vident.
Cas de rcurrence :
o On suppose que
est vraie.
o On doit montrer
, i.e. montrer quil est possible de dplacer une pile
de
disques dun axe vers un axe .
o Comme
est vraie, il est possible de dplacer les disques suprieurs de
notre pile de
disques vers laxe inutilis, que nous appellerons .

1
2
3
4
A

1
2
3
C

o Comme est vraie, il est possible de dplacer le disque de diamtre


vers laxe .

TP 52

Algorithmique et programmation

3/4

tours de Hano

4
A

1
2
3
C

4
B

o Comme
est vraie, il est possible de dplacer les
vers laxe .

disques de laxe

1
2
3

1
2
3
C

o On a montr
.
Conclusion :
est vraie pour tout

4
B

Exercice 7
crivez une fonction int deplace_disque(axe *a, axe *b) qui prend le disque situ
au sommet de laxe a et qui le place au sommet de laxe b. Si ce dplacement est impossible
(pile pleine, pile vide, diamtres des disques incompatibles), la fonction doit renvoyer
.
Sinon, elle renvoie 0.
Remarque : a et b sont des axes quelconques.

Exercice 8
crivez une fonction rafraichis_probleme(axe a, axe b, axe c) qui utilise
trace_probleme et les fonctions de la SDL pour redessiner le problme lcran. La
fonction doit :
Rinitialiser lcran avec efface_ecran ;
Dessiner ltat courant du problme avec trace_probleme ;
Rafraichir lcran avec rafraichis_ecran ;
Attendre pendant quelques millisecondes avec attend_delai.

Exercice 9
crivez une fonction rcursive resous_hanoi(int n, axe *a, axe *b, axe *c) qui
utilise le principe rcursif expliqu ci-dessus pour rsoudre le problme des tours de Hano.
On suppose que les axes passs en paramtres ont t pralablement initialiss. Le but est de
dplacer les disques suprieurs de laxe a vers laxe b. Donc, initialement on aura
.
Votre fonction devra afficher pas--pas le droulement de la rsolution, grce la fonction
rafraichis_probleme.
Remarque : pour avoir un aperu de ce qui vous est demand, excutez lun des fichiers
exempleWin.exe (pour Windows) ou exempleLnx (pour Linux) placs dans larchive fournie

avec ce sujet.

TP 52

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 53

remplissage de formes

1 Prsentation
Dans ce TP, nous nous intresserons des algorithmes qui permettent de remplir des
surfaces fermes avec une couleur de fond. On utilisera les notions vues prcdemment, en
particulier les piles, la rcursivit, et le calcul de complexit.

2 Prparation
On utilisera la terminologie suivante :
frontire : ensemble des pixels dlimitant la forme colorier.
couleur de fond : couleur initiale de la forme
couleur de remplissage : couleur utilise pour colorier la forme.
) situ dans la forme (pas sur la frontire) et
germe : pixel de coordonnes (
choisi au hasard.
germe
fond

coloriage

remplissage
frontire
avant le coloriage

aprs le coloriage

Vous trouverez avec ce sujet une archive contenant la bibliothque graphiques, dans
laquelle vous trouverez les fonctions dj utilises dans les TP prcdents, mais aussi la
fonction Uint32 couleurPixel(int x, int y), qui retourne le code couleur du pixel
de coordonnes (x ,y).
Larchive contient galement une bibliothque figures, qui vous permettra de tester
votre implmentation des algorithmes de remplissage. Cette bibliothque contient les
fonctions suivantes :
void rectangle(int x, int y, int largeur, int hauteur,
Uint32 coul) : dessine un rectangle dont le coin suprieur gauche a pour
coordonnes (x ,y) et dont les dimensions sont largeur et hauteur.
void flocon_von_koch(int n, Uint32 coul) : dessine un flocon de von
Koch (cf. le TP sur les figures fractales).
void trous(Uint32 coul) : dessine une figure comportant des trous.
Remarque : le flocon et la figure trous tant centrs sur lcran, vous pouvez choisir
).
comme germe le pixel central de coordonnes (
Enfin, larchive contient la bibliothque pile_liste permettant de manipuler des piles
dentiers, qui sera ncessaire pour lalgorithme du balayage horizontal.

TP 53

Algorithmique et programmation

1/4

remplissage de formes

Le programme main contient une variable COULEUR_FRONTIERE reprsentant la couleur


de la frontire, que vous devrez donc utiliser pour dessiner les figures remplir.

3 Remplissage par frontire


partir du germe, on applique lalgorithme rcursif suivant :
Cas darrt : le pixel courant est sur la frontire, ou bien il est dj de la couleur
de remplissage.
Cas gnral : le pixel nest pas sur la frontire et nest pas de la couleur de
remplissage :
o Il doit tre colori avec la couleur de remplissage.
o Le mme traitement est effectu sur les pixels situs en haut, en bas,
droite et gauche du pixel courant.

Exercice 1
crivez une fonction rcursive void remplissage_frontiere(int xg, int yg,
Uint32 coul) qui implmente cet algorithme.

Exercice 2
On suppose que les complexits spatiales et temporelles de couleur_pixel et
affiche_pixel sont toutes les deux en ( ). Calculez les complexits spatiale et
temporelle de votre fonction.

4 Balayage horizontal
Cet algorithme ncessite lutilisation dune pile de donnes dont chaque lment contient
les deux coordonnes dun pixel.
Initialisation :
o La pile est initialise avec le germe.
Traitement : tant que la pile nest pas vide
o Le sommet de la pile devient le pixel courant, la pile est dpile.
o Le segment horizontal contenant le pixel courant et dlimit par les
frontires de la forme est colori avec la couleur de remplissage.
o Un pixel de chacun des segments situs au-dessus ou au-dessous du
segment courant sont empils.
exemple :

Le pixel

est le germe, le segment


contenant est colori.
est dpil et les pixels , ,
et
sont empils.

P1

P2

TP 53

Algorithmique et programmation

P3
PG
P4

2/4

remplissage de formes

est dpil, le segment contenant


colori.

est empil.

est
P1

P3
PG

P2

P4
P5

est dpil, le segment contenant


colori.

et sont empils.

est
P1

P2
PG

P3

P6

P4

P5
P7

est colori puis dpil.


etc.
Lalgorithme se termine lorsque la pile est
vide
On remarque que le segment contenant
sera colori lors du dpilement de .

P1

P2
PG

P3

P6

P4
P5
P7

Exercice 3
Renommez les bibliothques pile_liste et liste_s en pile_liste_coord et
liste_s_coord. Modifiez-les ensuite de manire pouvoir utiliser des piles dont chaque
lment contient deux entiers x et y (et non plus un seul entier valeur).

Exercice 4
crivez une fonction int debut_segment(int x, int y) qui reoit les coordonnes
(x,y) dun point P, et qui dtermine (et renvoie par valeur) labscisse du point
situ le
plus gauche du mme segment horizontal.
exemple :

TP 53

Algorithmique et programmation

3/4

remplissage de formes

PD

Exercice 5
crivez une fonction void colorie_segment(int xd, int yd, Uint32 coul) qui
effectue la deuxime tape du traitement : le coloriage dun segment horizontal dlimit
gauche par le point de coordonnes (xd,yd) et droite par la frontire.
PD

Exercice 6
crivez une fonction void empile_suivants(pile *p, int xd, int yd, int
position, Uint32 coul) qui effectue le troisime point du traitement : la recherche des
segments suivants. En partant de la colonne xd, et en allant jusqu la frontire, la fonction
doit empiler dans p les pixels reprsentant les segments rencontrs sur la ligne
(yd+position). De cette manire, la mme fonction peut tre utilise pour dterminer les
segments suivants situs au-dessus du segment courant, et ceux situs au-dessous.
exemples :
position = -1

yd-1

P1

yd

PD

P2

position = +1
yd

PD

yd+1

P1

Exercice 7
crivez la fonction void balayage_horizontal(int xg, int yg, Uint32
coul) qui implmente lalgorithme de remplissage par balayage horizontal dcrit plus haut
en utilisant les fonctions prcdentes.

Exercice 8
On suppose que les complexits spatiales et temporelles des oprations sur les piles
(empile, depile, sommet, cree_pile) sont toutes en ( ). Calculez les complexits
spatiale et temporelle de votre fonction, puis comparez-les celles obtenues pour le
remplissage par frontire.

TP 53

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 54

parcours d'un labyrinthe

Prsentation
Dans ce TP, nous allons rsoudre le problme consistant trouver un chemin dans un
labyrinthe. Ceci nous permettra dillustrer la diffrence entre lutilisation de piles et de files
de donnes.

1 Introduction
Le Labyrinthe ponyme est un btiment construit par larchitecte Ddale pour enfermer le
Minotaure. Nous nous contenterons dun labyrinthe plus modeste, prenant la forme dune
figure gomtrique complexe, construite de manire ce quil soit difficile de la traverser. Le
but de ce TP est dimplmenter des algorithmes permettant de trouver un chemin allant de
lentre la sortie dun labyrinthe.
Larchive fournie avec le sujet contient notamment la bibliothque labyrinthe, qui
dfinit la dimension du labyrinthe grce la constante DIM_LABY, et les fonctions suivantes :
void initialise_labyrinthe_1(valeur_case laby[DIM_LABY][DIM_LABY]) :
initialise le tableau spcifi avec un labyrinthe.
void initialise_labyrinthe_2(valeur_case laby[DIM_LABY][DIM_LABY]) :
initialise le tableau avec un autre labyrinthe.
void
dessine_labyrinthe(valeur_case
laby[DIM_LABY][DIM_LABY]) :
dessine le labyrinthe correspondant au tableau spcifi.
Remarque : il est normal que des erreurs apparaissent la premire compilation, car lun
des types requis est manquant : il fait lobjet du premier exercice.

2 Reprsentation
Le labyrinthe sera reprsent en mmoire par une matrice carre (i.e. : un tableau deux
dimensions), chacun des lments du tableau correspondant une case du labyrinthe. La case
situe en haut gauche correspond lentre du labyrinthe, et celle situe en bas droite est
la sortie, comme reprsent dans le schma.
entre

0,0

0,1

,0

1,1

sortie

TP 54

Algorithmique et programmation

1/3

parcours d'un labyrinthe

La valeur contenue dans une case du tableau dpend de la nature de la case


correspondante dans le labyrinthe. On a les possibilits suivantes :
Case libre : case que lon peut parcourir et qui na pas encore t teste
(reprsente en gris sur le schma suivant).
Case courante : position courante (reprsente en bleu).
Case contenant un mur : case que lon ne peut pas chemin
parcourir (reprsente en marron).
parcouru
Case appartenant un chemin : case qui a dj t
impasse
parcourue (reprsente en jaune).
Case chec : case qui a dj t parcourue et qui
mur
constitue une impasse (reprsente en rouge).
case libre

Exercice 1
Dans la librairie labyrinthe, dfinissez un type numr
valeur_case permettant de reprsenter les
valeurs possibles
dune case du labyrinthe : libre, courante, mur, chemin et
echec.

position
courante

3 Rsolution du problme
La mthode la plus simple pour rechercher le chemin est dutiliser une file ou une pile
pour tester tous les chemins possibles jusqu tomber sur une solution.
Algorithme :
Initialement, la file (resp. pile) est vide.
On initialise la position courante avec lentre du labyrinthe.
On rpte le traitement suivant :
o On enfile (resp. empile) toutes les cases voisines de la position courante.
o On dtermine la nouvelle position courante :
On rcupre la case qui est en tte (resp. au sommet) de la file
(resp. pile).
On dfile (resp. dpile) la file (resp. pile).
Si la case est accessible alors elle devient la nouvelle position
courante.
Sinon on recommence avec la case suivante.
Si la file (resp. pile) est vide, alors la recherche est termine : il ny
a pas de solution.
Jusqu ce que la position courante soit la sortie du labyrinthe (succs) ou que la
file (resp. file) soit vide (chec).
Remarques :
Les cases voisines dune case donne sont les quatre cases situes au-dessus, audessous, gauche et droite.
On dit quune case est accessible si elle se situe lintrieur du labyrinthe et si sa
valeur dans le tableau est libre.
On dit quune case est une impasse si elle est dans le labyrinthe et si toutes ses
voisines sont inaccessibles.

Exercice 2
crivez une fonction int est_dans_labyrinthe(int x, int y) qui renvoie
case de coordonnes ( , ) est dans le labyrinthe, et sinon.
TP 54

Algorithmique et programmation

si la

2/3

parcours d'un labyrinthe

Exercice 3
crivez

une

fonction

int

est_accessible(valeur_case

[DIM_LABY], int x, int y) qui renvoie

et

laby[DIM_LABY]

si la case de coordonnes ( , ) est accessible,

sinon.

Exercice 4
crivez une fonction int est_impasse(valeur_case laby[DIM_LABY][DIM_LABY],
int x, int y) qui renvoie si la case de coordonnes ( , ) est une impasse, et sinon.

Exercice 5
La recherche de solution utilisant la file est appele recherche en largeur. crivez une
fonction void recherche_largeur(valeur_case laby[DIM_LABY][DIM_LABY]) qui
implmente lalgorithme prcdent en utilisant une file. Vous utiliserez pour cela la
bibliothque file_liste incluse dans le projet. Elle a t modifie de manire pouvoir
manipuler des lments contenant deux valeurs entires x et y.
Vous devez modifier les valeurs du tableau reprsentant le labyrinthe, de manire
indiquer les cases parcourues, les impasses et la position courante. Pour visualiser le
droulement de lalgorithme, vous utiliserez la fonction dessine_labyrinthe chaque
itration.

Exercice 6
La recherche de solution utilisant la pile est appele recherche en profondeur. En utilisant
bibliothque pile_liste et en respectant les mmes consignes que pour
recherche_largeur, crivez une fonction void recherche_profondeur(valeur_case
laby[DIM_LABY][DIM_LABY]) qui implmente lalgorithme de recherche en profondeur.
la

Exercice 7
Testez les deux types de recherche sur le premier labyrinthe. Quelles diffrences
remarque-t-on entre la recherche en profondeur et la recherche en largeur ? Testez-les sur le
second labyrinthe. Quen dduisez-vous ?

TP 54

Algorithmique et programmation

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 55

gnration dun labyrinthe

Prsentation
Ce TP est complmentaire de celui sur la recherche de chemin dans un labyrinthe. Il sagit
ici de gnrer des labyrinthes, de faon partiellement alatoire. Larchive fournie avec le sujet
contient certaines fonctions crites pour le TP prcdent, en particulier
dessine_labyrinthe et recherche_profondeur. De plus, le type numr
valeur_case, utilis pour reprsenter la nature des cases du labyrinthe, est dj cr.

1 Mthode par fusion


Il existe diffrentes mthodes pour gnrer alatoirement un labyrinthe. Nous allons
utiliser la mthode par fusion, qui fonctionne en manipulant des zones :
Une zone est un ensemble de cases accessibles.
labyrinthe contenant
Une zone est caractrise par un numro unique dans le
deux zones
labyrinthe.
1 1 1 1
1
Une zone est connexe (il est possible datteindre nimporte
1
1
1
quelle case de la zone partir de nimporte quelle autre case
2
1
de la zone).
1 1
Une zone est close (elle contient toutes les cases quon peut
atteindre partir de chaque case de la zone).
murs utiles
De plus, on dira quune case contenant un mur est utile si :
Soit toutes les cases voisines sont aussi des murs.
Soit la suppression du mur permet de fusionner au moins
deux zones diffrentes.
Algorithme :
Initialisation :
o On part dun labyrinthe dont les murs sont disposs de manire former
une grille.
o Chaque case libre constitue une zone. Les zones sont numrotes en partant
de pour la zone correspondant la case dentre.
Fusion :
o On slectionne alatoirement une case contenant un mur utile.
o Le mur est supprim, et les zones quil sparait sont fusionnes.
o La zone obtenue porte le plus petit numro des zones fusionnes.
o Si le mur utile tait entour de murs, une nouvelle zone est cre (avec un
nouveau numro).
On rpte la fusion jusqu ce quil ny ait plus quune seule zone.
exemple :

TP 55

Algorithmique et programmation

1/3

gnration dun labyrinthe

10

11

12

14

15

16

9
9
9

17
9

10

11

12

10

11

12

16

9
9
9

13

14

15

14

15

16

7
7 7
7
9 9 9
9
14
15
9

5 5 5

7
7 7
9 9 9
7
9
9
14
15

12
16

9
9
9

12
16

7
7 7
10
7

8
12

14

16

1 1 1
1
1 1 1
1
1 1 1
1
1
1
1

15

1 1
1
1
1
1 1 1
1 1
1 1 1
1
1
1 1
1

Contrairement au TP prcdent, nous allons dans un premier temps reprsenter le


labyrinthe sous la forme dune matrice dentiers, et non pas de valeurs de type
valeur_case. On appellera cette structure un pseudo-labyrinthe. On utilisera la valeur
pour reprsenter les murs, et toute autre valeur positive correspondra au numro dune zone
(donc une case libre). Cela signifie donc que les zones sont numrotes partir de .
La fonction dessine_pseudo_labyrinthe contenue dans la bibliothque labyrinthe
est fournie spcifiquement pour afficher ce type de matrice entire : chaque zone est
reprsente dune couleur diffrente.

Exercice 1
fonction
int
initialise_grille(int
pseudo[DIM_LABY][DIM_LABY]) qui dispose les murs dans le pseudo-labyrinthe de
manire former une grille, et qui numrote les cases libres. La fonction doit renvoyer le
nombre de zones cres.
crivez

une

Exercice 2
crivez une fonction int est_utile(int pseudo[DIM_LABY][DIM_LABY], int
) est utile, et sinon.
x, int y) qui renvoie si le mur de coordonnes (

Exercice 3
void
remplace_valeur(int
pseudo[DIM_LABY][DIM_LABY], int ancienne, int nouvelle) qui remplace dans
le tableau pseudo toute occurrence de la valeur ancienne par une occurrence de la valeur
nouvelle.

crivez

une

fonction

Exercice 4
crivez une fonction void supprime_mur(int pseudo[DIM_LABY][DIM_LABY],
). La fonction
int x, int y, int *n) qui supprime le mur situ aux coordonnes (
doit galement dterminer les zones fusionner puis effectuer la fusion (grce la fonction
). Le paramtre
remplace_valeur), en noubliant pas de traiter la case de coordonnes (
n sera ventuellement utilis pour numroter une nouvelle zone.

Exercice 5
fonction
int
teste_zone_unique(int
pseudo[DIM_LABY][DIM_LABY]) qui renvoie
sil ny a quune seule zone dans le
pseudo-labyrinthe, et sinon.
crivez

une

Exercice 6

TP 55

Algorithmique et programmation

2/3

gnration dun labyrinthe

labyrinthe contient une fonction void


tire_mur(int
pseudo[DIM_LABY][DIM_LABY], int *x, int *y) qui tire au sort un des murs du

La

bibliothque

pseudo-labyrinthe et qui renvoie ses coordonnes par les paramtres x et y.


Utilisez cette fonction ainsi que les fonctions prcdentes pour crire une fonction void
genere_pseudo_labyrinthe(int
pseudo[DIM_LABY][DIM_LABY]) qui gnre
alatoirement un pseudo-labyrinthe en utilisant lalgorithme dcrit plus haut. Vous devez
utiliser dessine_pseudo_labyrinthe pour donner le dtail pas--pas de cette
construction.

Exercice 7
On veut appliquer notre labyrinthe un algorithme de recherche de chemin crit lors du
TP prcdent. Mais pour cela, on a besoin dune matrice contenant des valeurs de type
valeur_case et non pas des entiers.
crivez
une
fonction
convertis_labyrinthe(int
pseudo[DIM_LABY][DIM_LABY], valeur_case laby[DIM_LABY][DIM_LABY]) qui
reoit un pseudo-labyrinthe pseudo dj cr avec genere_pseudo_labyrinthe, ainsi
quun labyrinthe vide laby, et qui initialise laby grce aux valeurs contenues dans pseudo.

Exercice 8
Dans la fonction main, crez un pseudo-labyrinthe avec genere_pseudo_labyrinthe,
puis convertissez-le grce convertis_labyrinthe pour obtenir un labyrinthe, et enfin
appliquez recherche_profondeur pour en trouver la solution.

TP 55

Algorithmique et programmation

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 56

tri par dnombrement

Prsentation
Dans ce TP, on veut implmenter le tri par dnombrement, qui na pas t tudi en
classe. Nous allons pour cela dvelopper une bibliothque tri_tab, qui sera ddie au tri de
tableaux dentiers.

1 Initialisation
Exercice 1
Crez les fichiers dune nouvelle bibliothque tri_tab. Dfinissez-y une constante N
correspondant la taille des tableaux que lon voudra trier.

Exercice 2
On veut pouvoir initialiser des tableaux non-tris, de faon alatoire. Pour cela, nous
allons nous servir des fonctions srand et rand, qui ont dj t utilises plusieurs fois dans
des TP prcdents. Pour rappel :
void srand(unsigned int seed) : initialise le gnrateur pseudo-alatoire
en prenant le paramtre seed comme graine. Il ne faut lutiliser quune seule fois,
elle est ncessaire la cration de la srie de nombres.
int rand(void) : renvoie lentier suivant dans la srie pseudo-alatoire. La
srie doit dabord avoir t initialise avec srand. Lentier obtenu est compris
entre et la constante RAND_MAX (inclus).
Ce gnrateur pseudo-alatoire approxime une distribution uniforme, c'est--dire que la
[
] apparaisse quand on utilise rand est de
probabilit quun entier
(
).
Il faut remarquer que toute la srie de nombres dpend compltement et uniquement de la
graine utilise pour initialiser le gnrateur. Par consquent, si on utilise plusieurs fois la
mme graine, on obtiendra exactement les mmes valeurs, et dans le mme ordre. Pour viter
cette rptition, il est ncessaire dutiliser une graine diffrente chaque initialisation du
gnrateur.
La fonction time(NULL) renvoie une valeur de type long correspondant au nombre de
secondes coules depuis le 1er janvier 1970 00:00:00. Ce nombre varie en permanence, et il
constitue donc une bonne graine.
Dans tri_tab, crivez une fonction int genere_entier(int inf, int sup) qui
]. La premire fois
renvoie un entier gnr pseudo-alatoirement et appartenant [
quelle est appele (et uniquement cette fois-l) votre fonction doit initialiser le gnrateur
grce srand.
Remarque : pensez aux diffrentes classes de mmorisation dune variable.

Exercice 3

TP 56

Algorithmique et programmation

1/3

tri par dnombrement

Dans tri_tab, crivez une fonction void affiche tableau(int tab[], int
taille) permettant dafficher un tableau contenant taille lments.
exemple : pour tab={1,5,6,9,77,1,5,6}, on doit obtenir :
{1 5 6 9 77 1 5 6}

Exercice 4
Dans tri_tab, crivez une fonction void init_tableau(int tab[N], int n)
].
qui initialise pseudo-alatoirement un tableau de taille avec des entiers appartenant [
exemple : un appel avec n=10 pourrait gnrer quelque chose comme
{1,4,0,5,7,3,1,6}.

Exercice 5
Pour tester certains tris, il est prfrable que chaque valeur dans le tableau soit unique.
Dans tri_tab, crivez une fonction void init_tableau_unique(int tab[N], int
n) qui initialise pseudo-alatoirement un tableau de taille
avec des entiers appartenant
[
], de manire a ce quaucun doublon napparaisse (i.e. la mme valeur ne doit pas
apparatre plusieurs fois dans le tableau.
Remarque : la fonction ne peut marcher correctement que si on a
.
exemples :
Le tableau de lexemple prcdent ne peut pas tre gnr par cette fonction, car il
contient deux fois la valeur .
Par contre, le tableau {1,4,0,5,7,3,2,6} pourrait tre gnr par cette
fonction.

2 Algorithme de tri
[, une mme valeur pouvant
On veut trier un tableau tab1 de entiers appartenant [
apparatre plusieurs fois dans le mme tableau. Nous allons pour cela utiliser le tri par
dnombrement (galement appel tri comptage ou tri casier). Il sagit dune mthode de tri
diffrente de celles vues en cours, car ici on ne compare pas directement les lments de la
squence entre eux.
Lalgorithme comprend 3 tapes :
1re tape : dnombrement
o On dnombre (i.e. on compte) combien de fois chaque valeur de tab1
apparat dans tab1.
o Ces dnombrements sont stocks dans un tableau tab2 de taille .
[
[, la valeur contenue dans tab2[v] reprsente le
o Pour tout
nombre doccurrences de dans tab1.
2me tape : distribution
o On calcule la distribution cumulative de tab1 grce tab2.
o On stocke le rsultat dans un tableau tab3 de taille .
[
[, la valeur contenue dans tab3[v] reprsente le
o Pour tout
nombre de valeurs dans tab1 qui sont infrieures ou gales .
3me tape : construction
o On construit le tableau tri tab4 partir du tableau initial tab1 et de sa
distribution tab3.
o En partant de la fin de tab1, on considre chaque valeur .
o La valeur de distribution tab3[v] correspond au nombre de valeurs
infrieures ou gales . Donc cette valeur de distribution peut tre utilise
pour dterminer la position de dans le tableau tri tab4.

TP 56

Algorithmique et programmation

2/3

tri par dnombrement

o On dcrmente la valeur tab3[v], puis on insre


exemple :

et
tab1

tab1

4 5 2 1 4

tab3
tab4
tab1

tab2

0 1 1 0 2 1

tab3
tab4
tab1

tab3

dans tab4[tab3[v]].

0 1 2 2 4 5

tab3
tab4

4 5 2 1 4
0 1 2 2 4 5
- - - - -

tab1

4 5 2 1 4
0 1 2 2 3 5
- - - 4 -

tab1

4 5 2 1 4
0 0 2 2 3 5
1 - - 4 -

tab1

tab3
tab4

tab3
tab4

tab3
tab4

4 5 2 1 4
0 0 1 2 3 5
1 2 - 4 4 5 2 1 4
0 0 1 2 3 4
1 2 - 4 5
4 5 2 1 4
0 0 1 2 2 4
1 2 4 4 5

Exercice 6
Dans tri_tab, dfinissez une constante M correspondant la borne suprieure des
valeurs places dans les tableaux trier. Puis, toujours dans tri_tab, crivez une fonction
void calcule_denombrement(int tab1[N], int tab2[M]) qui dnombre les
valeurs du tableau tab1 et place le rsultat de ce dnombrement dans le tableau tab2.
exemple : pour N=10, M=5, tab1={0,1,3,1,0,1,1,4,0,0}, on obtient
tab2={4,4,0,1,1}.
Remarque : attention lorsque vous utilisez init_tableau lors du test de votre fonction, car
], et non pas dans [
[.
celle-ci gnre des entiers dans [

Exercice 7
Dans tri_tab, crivez une fonction void calcule_distribution(int tab2[M],
tab3[M]) qui calcule le tableau de distribution tab3 grce au tableau de
dnombrement tab2.
exemple : pour N=10, M=5, tab2={4,4,0,1,1} on obtient tab3={4,8,8,9,10}.
int

Exercice 8
Dans tri_tab, crivez une fonction void calcule_construction(int tab1[N],
int tab3[M], int tab4[N]) qui remplit le tableau tri tab4 grce au tableau initial
tab1 et au tableau de distribution tab3.
exemple : pour N=10, M=5, tab1={0,1,3,1,0,1,1,4,0,0}, tab3={4,8,8,9,10},
on obtient tab4={0,0,0,0,1,1,1,1,3,4}.

Exercice 9
En utilisant les fonctions prcdentes, crivez dans tri_tab une fonction void
tri_denombrement(int tab1[N], int tab4[N]) qui trie le tableau tab1 et stocke le
rsultat de ce tri dans le tableau tab4.
exemple : pour N=10, M=5, tab1={0,1,3,1,0,1,1,4,0,0}, on obtient
tab4={0,0,0,0,1,1,1,1,3,4}.

Exercice 10
Calculez la complexit spatiale de tri_denombrement. Ce tri est-il en place ? Est-il
stable ?

TP 56

Algorithmique et programmation

3/3

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut

TP 57

Universit
Galatasaray

tri Cocktail

Prsentation
Le but de ce TP est dapprofondir la notion de complexit algorithmique via un tri qui na
pas t vu en cours : le tri Cocktail. Nous lappliquerons des tableaux dentiers, comme en
cours et dans les TP prcdents. Pour vous aider, la bibliothque tri_tab est fournie avec ce
sujet.

1 Version itrative
Le tri cocktail est une variante du tri bulle, utilisant une bulle bidirectionnelle. Dans le tri
bulle, chaque cycle, la bulle traverse le tableau toujours dans le mme sens, en gnral du
dbut vers la fin.
Dans le tri cocktail, la bulle effectue des allez-retours entre le dbut et la fin du tableau. De
plus, on ne considre pas le tableau entier, mais seulement un sous-tableau, qui est rduit dun
lment chaque cycle. En effet, on considre qu la fin dun cycle, le dernier lment trait a
atteint sa place dfinitive.
exemple :
Cycle 1
Cycle 2
Cycle 4
5

Cycle 3
2

Lgende :
les lments encadrs sont les lments compars.
les lments foncs sont les lments qui ont t changs.
les lments blancs sont les lments qui ne font pas partie du sous-tableau
courant.

Exercice 1
crivez une fonction void tri_cocktail_it(int tab[N]) charge dappliquer le tri
cocktail dcrit ci-dessus un tableau dentiers tab de taille N.

Exercice 2

TP 57

Algorithmique et programmation

1/2

tri Cocktail

Quelles sont les proprits de ce tri (caractre en place et stabilit) ?

Exercice 3
Calculez les complexits asymptotiques spatiale et temporelle de votre fonction, dans le
pire des cas, en dtaillant vos calculs comme en cours.

2 Comparaison avec le tri bulle


Exercice 4
Comparez les complexits temporelles du tri bulle et du tri cocktail : que pouvez-vous
en dduire ?

Exercice 5
On veut maintenant comparer les deux algorithmes, mais pas de faon asymptotique. Pour
cela, on va sintresser aux nombres de comparaisons et dchanges (entre deux entiers du
tableau) effectus par chaque algorithme. Ainsi, dans lexemple prcdent, le tri cocktail
effectue
comparaisons et changes.
Soit le tableau tab={7,4,2,8,3,1}. En utilisant la mme prsentation que dans
lexemple du sujet, appliquez ce tableau les deux algorithmes de tri. Dterminez le nombre
de comparaisons et dchanges effectus par chaque algorithme.
Remarque : vous utiliserez la version du tri bulle prsente en cours.
Lequel des deux algorithmes est le plus efficace pour trier tab ? Cela est-il cohrent avec
la conclusion que vous aviez tire de la comparaison de leurs complexits temporelles
asymptotiques ?

3 Version rcursive
Exercice 6
crivez une fonction rcursive void tri_cocktail_rec(int tab[N], int deb, int
fin, int direction) implmentant le tri cocktail. Chaque appel de cette fonction doit
correspondre un cycle du tri.
Le paramtre tab correspond au tableau trier, deb et fin sont respectivement les index
des lments marquant le dbut et la fin du sous-tableau courant, et direction indique le
sens de parcours du tableau : (du dbut vers la fin) ou (de la fin vers le dbut).

Exercice 7
Calculez la complexit temporelle asymptotique dans le pire des cas de la fonction
tri_cocktail_rec.

TP 57

Algorithmique et programmation

2/2

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 58

reprsentation des tris

Prsentation
Dans ce TP, lobjectif est dimplmenter une reprsentation graphique de certains tris vus
en cours. Pour cette raison, ce sujet est fourni avec deux bibliothques : graphisme, qui
permet dutiliser la SDL et a dj t utilise de nombreuses fois, et tri_tab qui contient des
algorithmes de tri implments pour traiter des tableaux dentiers. Les fonctions crire pour
ce TP seront toutes placer dans la bibliothque tri_tab ( lexception de la fonction
principale main, bien entendu).

1 Reprsentation des donnes


On sinspire des vidos de ce type, dans lesquelles chaque entier du tableau trier est
reprsent par un rectangle dont :
La hauteur correspond la de lentier ;
La position horizontale (abscisse) correspond lindex de lentier dans le tableau.
exemple : pour un tableau {4,1,0,3,1,2,1,3,2,2,1,0,3,4}, on veut obtenir
quelque chose du type :

Pour rendre la reprsentation plus lisible, on alternera une teinte fonce et une teinte claire
de la mme couleur, comme ci-dessus avec le gris (le 1er rectangle est gris clair, le 2me gris
fonc, etc.). De plus, on utilisera trois couleurs diffrentes :
Gris pour reprsenter les lments qui nont pas encore t traits ;
Rouge pour reprsenter les lments qui sont en train dtre dplacs ou changs ;
Bleu pour reprsenter les lments qui ont atteint leur position finale (i.e. ils sont
au bon endroit dans le tableau).
cela, on peut rajouter la couleur noir, qui permettra deffacer un rectangle (en dessinant
un rectangle noir par-dessus).

Exercice 1
Dans tri_tab, crivez une fonction void dessine_valeur(int index, int
valeur, int mode) qui dessine le rectangle correspondant la valeur spcifie, sachant
quelle se trouve la poisition index. Le paramtre index est une valeur numrique indiquant
la couleur utiliser :

: noir ;

: gris (valeur pas encore traite) ;


TP 58

Algorithmique et programmation

1/4

reprsentation des tris

: rouge (valeur en cours de traitement) ;

: bleu (valeur occupant sa position finale).


Vous devez utiliser les constantes de tri_tab : N (nombre dlments le tableau) pour
dterminer la position horizontale du rectangle et M (valeur maximale dun lment) pour
dterminer sa hauteur, de manire occuper au maximum lespace disponible dans la fentre.
Pensez utiliser les constantes FENETRE_LARGEUR et FENETRE_HAUTEUR de graphisme.
exemple : pour les instructions suivantes, avec N=100 et M=100, on obtient exactement
laffichage ci-dessous :
dessine_valeur(10,25,1);
dessine_valeur(11,25,1);
dessine_valeur(12,30,1);
dessine_valeur(13,12,1);
dessine_valeur(20,40,2);
dessine_valeur(21,38,2);
dessine_valeur(22,57,2);
dessine_valeur(30,10,3);
dessine_valeur(31,0,3);
dessine_valeur(32,18,3);
dessine_valeur(33,36,3);
raffraichis_fenetre();

Remarque : pour des raisons de rapidit, la fonction raffraichis_fenetre ne doit


pas tre appele dans votre fonction dessine_valeur.

Exercice 2
Selon le mme principe, crivez dans tri_tab une fonction void
dessine_tableau(int tab[N], int mode) qui effectue laffichage dun tableau
entier.
Remarque : cette fois, la fonction raffraichis_fenetre doit tre appele directement
depuis votre fonction dessine_tableau.

Exercice 3
Toujours daprs le mme principe, crivez dans tri_tab une fonction void
dessine_sous_tableau(int tab[N], int debut, int fin, int mode) qui
effectue laffichage de la partie du tableau comprise entre les positions debut et fin
(incluses).
Remarque : votre fonction dessine_sous_tableau doit aussi appeler
raffraichis_fenetre.

Exercice 4
Lopration dinterversion est commune plusieurs algorithmes de tri. Elle consiste
changer les positions de deux valeurs du tableau. Dans tri_tab, crivez une fonction void
echange_valeurs(int tab[N], int i, int j) qui ralise cet change de valeurs,
ainsi que laffichage graphique appropri.
Lalgorithme est le suivant :
1. Effacer les rectangles reprsentant les deux valeurs actuelles, en dessinant des
rectangles noirs par-dessus ;
2. Mettre jour le tableau (i.e. changer les valeurs numriques) ;
3. Dessiner les nouveaux rectangles en rouge ;
4. Rafrachir et attendre un certain dlai (qui peut tre fix par une constante
DELAI) ;
5. Dessiner les mmes rectangles en gris, sans rafraichir cette fois.

TP 58

Algorithmique et programmation

2/4

reprsentation des tris

Certaines de ces tapes sont illustres par le schma suivant, dans lequel on veut
intervertir les entiers situs aux positions 0 et :
avant
1
3
5

Exercice 5
Une opration plus simple qui apparait dans certains algorithmes (gnralement ceux qui
ne sont pas des tris sur place) consiste simplement craser une valeur existante. Dans
tri_tab, crivez une fonction void ecrase_valeur(int tab[N], int i, int
valeur) qui remplace la valeur de tab[i] par valeur, et qui modifie laffichage de faon
approprie :
1. Effacer le rectangle reprsentant tab[i] ;
2. Mettre jour le tableau tab ;
3. Dessiner le nouveau rectangle en rouge ;
4. Rafrachir et attendre un certain dlai ;
5. Dessiner le mme rectangle en gris, sans rafraichir.

2 Algorithmes de tri
Exercice 6
Dans tri_tab, modifiez la fonction du tri bulles, tri_bulles, de manire :
Afficher le tableau entier en gris avant de traitement ;
Raliser le tri en utilisant echange_valeurs ;
Ajouter un appel dessine_valeur dans la boucle principale, pour afficher en
bleu les valeurs qui ont atteint leur position finale ;
Afficher le tableau entier en bleu la fin du traitement.
Les captures dcran ci-dessous reprsentent laffichage obtenu au dbut, au milieu et la
fin du traitement :

Remarque : pour faciliter votre travail, il est recommand de :


Commencer par afficher lvolution du traitement sans se soucier des couleurs ;
Puis introduire la couleur rouge ;
Et enfin la couleur bleue.

Exercice 7
Mme chose pour le tri par slection.

Exercice 8

TP 58

Algorithmique et programmation

3/4

reprsentation des tris

Pour le tri par insertion, il ny a pas dinterversion, donc vous ne devez pas utiliser
echange_valeurs, mais plutt ecrase_valeur. On reprsentera en bleu la partie du
tableau qui est dj trie.

Exercice 9
Il ny a pas non plus dinterversion dans le tri fusion, donc vous devez aussi utiliser
ecrase_valeur plutt quechange_valeurs .
Vous remarquerez que limplmentation de la bibliothque tri_tab nest pas tout fait
la mme que celle vue en cours : elle a t modifie pour permettre laffichage que lon veut
raliser aujourdhui. En particulier, tous les tableaux manipuls sont de taille N, et les soustableaux sont spcifis en utilisant des paramtres supplmentaires debut et fin, qui
indiquent le dbut et la fin du sous-tableau.
On utilisera la couleur bleue pour reprsenter la fin dune tape de fusion, et ainsi indiquer
lemplacement final relativement un sous-tableau, comme ci-dessous :

Exercice 10
Pareil pour le tri rapide, et cette fois vous devez utiliser echange_valeur.

Remarque : le tri par dnombrement ne se prte pas vraiment ce type de reprsentation


graphique, aussi il ne sera pas trait.

TP 58

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut

TP 59

Universit
Galatasaray

tris sur listes

Prsentation
Dans ce TP, nous allons adapter certains des algorithmes de tri vus en cours, qui taient
destins aux tableaux, afin de les appliquer des listes. Pour cette raison, la bibliothque
liste_d est fournie avec ce sujet.
Remarque : pensez la fonction initialise_liste_d pour initialiser rapidement une
liste.

1 Tri par slection


Exercice 1
crivez une fonction element* identifie_extremum(liste_d l, int mode) qui
parcourt une liste et retourne un pointeur sur llment contenant sa valeur la plus extrme. Le
mode indique de quel extremum il sagit : 0 pour le minimum et 1 pour le maximum. Si la
valeur extrme apparait plusieurs fois dans la liste, la fonction doit renvoyer le premier
lment contenant cette valeur. Si la liste est vide, la fonction doit renvoyer NULL.
):
exemples : pour la liste (
Le mode renvoie le premier lment (min) ;
Le mode renvoie le dernier lment (max).

Exercice 2
crivez une fonction void tri_selection_rec(liste_d *l) qui effectue
rcursivement le tri de la liste l dans lordre croissant en utilisant lalgorithme du tri par
slection. La version rcursive de cet algorithme est :
Si la liste contient un seul lment (ou aucun) : elle est dj trie.
Sinon :
o Identifier et extraire le minimum dans la liste de longueur ;
o Trier la sous-liste obtenue, dont la longueur est
;
o Insrer le minimum au dbut de cette sous-liste trie, pour obtenir la liste
complte trie.
exemple :
Liste initiale
NULL 18

1 NULL

On identifie et on extraie le minimum de la liste


NULL 18

TP 59

1 NULL

Algorithmique et programmation

NULL 0 NULL

1/4

On trie rcursivement la sous-liste


NULL 1

18 NULL
e

NULL 0 NULL

On insre le minimum au dbut de la sous-liste trie


NULL 0

18 NULL

Remarque : notez que la bibliothque liste_d contient une fonction int


detache_element(liste_d *l, element_d *e) (crite lors dun TP prcdent) qui
permet de retirer llment e de la liste l, sans supprimer llment e. Elle renvoie
en cas
derreur.

Exercice 3
crivez une fonction void tri_selection_it(liste_d *l) qui effectue le mme
travail que la fonction prcdente, mais cette fois ci de manire itrative. La version itrative
de cet algorithme est :
Crer une liste vide rsultat ;
Tant que la liste l nest pas vide :
o Identifier et extraire son maximum ;
o Insrer le maximum au dbut de la liste rsultat ;
exemple :
Liste initiale
NULL 18

1 NULL

resultat
NULL NULL

On identifie et on extraie le maximum de la liste, puis on linsre au dbut de la liste rsultat


NULL 3

1 NULL

NULL 18 NULL

resultat

On recommence
NULL 3

1 NULL

NULL 7

18 NULL
resultat

On continue, jusqu ce que la liste soit vide: la liste rsultat obtenue est dans lordre croissant
NULL 0

18 NULL

resultat

NULL NULL

2 Tri par insertion


Exercice 4
crivez une fonction int insere_element_trie(liste_d *l, element_d *e)
qui insre un lment e au bon endroit dans une liste l trie dans lordre croissant. Vous ne

TP 59

Algorithmique et programmation

2/4

devez utiliser aucune fonction de la bibliothque liste_d. La fonction renvoie


derreur et en cas de succs.
), alors on obtient (
exemple : si la fonction doit insrer
dans (

en cas
).

Exercice 5
crivez une fonction itrative void trie_insertion(liste_d *l) qui applique
lalgorithme du tri par insertion une liste dentiers l. Vous utiliserez la fonction
insere_element_trie pour raliser les insertions.
Pour rappel, le principe du tri par insertion est de diviser la liste initiale trier en deux
sous-listes : une sous-liste trie et une sous-liste non-trie.
Initialisation :
o La sous-liste trie est initialement vide ;
o La sous-liste trier contient tous les autres lments.
Traitement : pour chaque lment de la sous-liste non-trie :
1. On enlve cet lment de la sous-liste non-trie ;
2. On linsre au bon endroit dans la sous-liste trie.
la fin du traitement, la sous-liste non-trie est vide et la sous-liste trie contient tous les
lments de la liste initiale, rangs dans le bon ordre.
exemple :
Liste originale
l NULL

18

Cycle 2
1

32 NULL

Initialisation

trie NULL

18 NULL

nontrie NULL

32 NULL

Cycle 3

trie -

trie NULL

nontrie NULL

18

32 NULL

Cycle 1
trie NULL

18 NULL

nontrie NULL

nontrie NULL

18 NULL

32 NULL

Cycle 4
trie NULL

32 NULL

18

32 NULL

non- trie

3 Tri fusion
Le principe de lalgorithme du tri fusion est rcursif. Il est dcrit par les cas suivants :
Cas darrt : la liste est vide ou ne contient quun seul lment (elle est dj trie) ;
Cas gnral : il se compose de trois phases :
o Division : la liste est coupe en deux parties de mme longueur ( un
lment prs) ;
o Tri : chaque moiti de liste est trie sparment et rcursivement ;
o Fusion : les deux moitis tries sont fusionnes pour obtenir une version
trie de la liste initiale
exemple :

TP 59

Algorithmique et programmation

3/4

tris sur listes

Division
NULL 85

18

NULL 85

18 NULL

NULL 85 NULL

NULL 1

NULL 18 NULL

5 NULL

32

5 NULL

32

NULL 1 NULL

5 NULL

NULL 32

NULL 32 NULL

NULL 5 NULL

Fusion
NULL 1

NULL 18

NULL 85 NULL

18

85 NULL

NULL 1

NULL 18 NULL

85 NULL

32

32 NULL

NULL 1 NULL

NULL 5

NULL 32 NULL

32 NULL

NULL 5 NULL

Exercice 6
crivez une fonction element_d* renvoie_milieu(liste_d l) prenant une liste l
en paramtre et renvoyant un pointeur vers son lment central. Pour une liste de lments,
on considre que llment central est le (
)me. On suppose que la liste reue contient
au moins deux lments.
) ou (
), la fonction renvoie un pointeur sur
exemple : si la liste l est (
llment contenant .

Exercice 7
crivez une fonction void calcule_division(liste_d l, liste_d *lg,
liste_d *ld) prenant en paramtres une liste l contenant au moins deux lments, et deux
listes lg et ld initialises mais vides. Votre fonction doit utiliser renvoie_milieu pour
couper l en deux sous-listes lg et ld de mme longueur, un lment prs.
), alors lg et ld seront respectivement (
) et
exemple : si la liste l est (
(
).

Exercice 8
crivez une fonction void calcule_fusion(liste_d *l, liste_d lg,
liste_d ld) recevant en paramtre une liste l quelconque, et deux sous-listes dj tries
dans lordre croissant lg et ld. Votre fonction doit initialiser l avec lunion de lg et ld, tout
en prservant lordre croissant. On suppose que lg et ld sont toutes les deux non-vides.
) et ld est (
) alors l est (
).
exemple : si lg est (

Exercice 9
crivez une fonction rcursive void tri_fusion(liste_d *l) qui prend en
paramtre une liste l et la trie dans lordre croissant en appliquant lalgorithme du tri fusion.
Vous utiliserez pour cela les fonctions division et fusion prcdemment crites.

TP 59

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 60

reprsentation de lADN

Prsentation
Le but de ce TP est de manipuler des listes reprsentant des
brins dADN, de faon itrative et rcursive. La fin du TP est
consacre au calcul de complexit algorithmique.

1 Codage de linformation
LADN (acide dsoxyribonuclique) est une molcule
utilisant une reprsentation de linformation spcifique
(gnotype) pour reprsenter les caractristiques des tres
vivants et de certains virus (phnotypes). Cette information
gntique est code grce un alphabet de quatre bases
azotes : adnine (A), cytosine (C), guanine (G) et thymine (T).
On peut considrer un brin dADN comme une squence
forme avec ces quatre bases.

Exercice 1
On veut reprsenter un brin dADN par une liste simplement chane dont chaque lment
reprsente une base azote. Une base azote sera reprsente par un caractre (A, C, G ou T).
Modifiez la structure et/ou les en-ttes de la bibliothque liste_s fournie en annexe, de
manire ladapter au cas de lADN.

Exercice 2
crivez une fonction rcursive int est_adn(liste_s brin) qui teste si la liste brin
passe en paramtre correspond bien un brin dADN (i.e. est une squence de bases
azotes). La fonction renvoie si la liste reprsente bien un brin dADN, et sinon.
exemples :
Pour la squence A-T-G-C-G-C : la fonction doit renvoyer .
Pour la squence A-T-G-C-D-G : la fonction doit renvoyer .

Exercice 3
crivez une fonction int genere_adn(liste_s *brin, int n) qui cre un brin
dADN en combinant alatoirement les quatre bases de manire obtenir une squence de
longueur n. Lors de lappel de la fonction, la liste brin est vide. La fonction renvoie
en
cas derreur et en cas de succs.
Vous devez utiliser les fonctions srand(unsigned int) et rand() dj vues en TP,
de manire ce que le brin gnr soit diffrent chaque appel de la fonction.

2 Structure en double hlice


L'ADN est compos de deux brins se faisant face, et formant une double hlice (cf. la
figure en dbut de sujet). Chaque base azote dun des brins fait face sa base

TP 60

Algorithmique et programmation

1/2

reprsentation de lADN

complmentaire situe sur lautre brin. Ladnine et la thymine sont complmentaires, tandis
que la cytosine et la guanine sont complmentaires.
exemple : les brins A-T-G-C-T-T-T-A-G et T-A-C-G-A-A-A-T-C sont complmentaires.

Exercice 4
int
calcule_complementaire(liste_s
original, liste *complementaire) qui prend en paramtre une liste original

crivez

une

fonction

rcursive

reprsentant un brin dADN, et une liste vide (mais correctement initialise)


complementaire. La fonction doit remplir complementaire de manire obtenir une
squence complmentaire original. La fonction renvoie
en cas derreur et en cas de
succs.
exemple : pour la squence A-T-G-C-A-A, la fonction doit renvoyer la squence T-A-CG-T-T.

Exercice 5
crivez une fonction rcursive int sont_egales(liste_s brin1, liste_s
brin2) qui compare deux brins dADN reprsents par les listes brin1 et brin2. La
fonction renvoie si les deux brins sont constitus de la mme squence de bases azotes, et
sinon.
exemples :
Pour A-T-C et A-T-C : la fonction renvoie .
Pour A-T-C et A-T-G : la fonction renvoie .
Pour A-T-C et A-T-C-G : la fonction renvoie .

Exercice 6
crivez une fonction int
sont_complementaires(liste brin1, liste brin2) qui teste si les deux brins
passs en paramtres sont complmentaires. La fonction renvoie si les deux brins sont
complmentaires, sils ne sont pas complmentaires, et
en cas derreur.
exemples :
Pour A-T-C et T-A-G : la fonction renvoie .
Pour A-T-C et A-A-G : la fonction renvoie .
Pour A-T-C et T-A-G-C : la fonction renvoie .
En

utilisant

les

deux

fonctions

prcdentes,

Exercice 7
Calculez la complexit temporelle asymptotique de la fonction sont_complementaires
dans le pire des cas (pensez utiliser le formulaire donn en cours).
Remarque : on considre que les fonctions de la bibliothque liste_s ont les
complexits temporelles asymptotiques suivantes :
Crer un lment ou insrer/supprimer/accder au premier lment de la liste :
( ).
Afficher la liste ou insrer/supprimer/accder un lment quelconque de la liste :
( ).

TP 60

Algorithmique et programmation

2/2

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 61

nombres de grande taille

Prsentation
Le but de ce TP est de manipuler les listes chanes et le traitement rcursif, travers la
reprsentation et le calcul de nombres de grande taille. Pour cette raison, la bibliothque
liste_s est fournie avec ce sujet.
Pour simplifier les calculs de complexit, on considrera que toutes les fonctions
contenues dans cette bibliothque ont une complexit asymptotique temporelle dans le pire
des cas en ( ).
Notez que la bibliothque liste_s contient une fonction initialise_liste_s
permettant dinitialiser rapidement une liste partir dun tableau dentier. Lordre des valeurs
dans le tableau est reproduit dans la liste.

1 Reprsentation
Les types simples du langage C ne permettent pas de manipuler des entiers de grandes
tailles, c'est--dire des entiers dont lcriture comporte beaucoup de chiffres. Une solution
consiste reprsenter un tel nombre sous la forme dune liste doublement chaine, dans
laquelle chaque lment correspond un chiffre.
De plus, pour des raisons pratiques, on prfrera placer les chiffres dans lordre inverse de
lordre habituel (i.e. en partant du chiffre de poids le plus faible, au lieu de celui de poids le
plus fort). En effet, les nombres entiers sont manipuls la plupart du temps en partant des
units. Cest notamment le cas pour les oprateurs arithmtiques de type addition,
multiplication, soustraction, etc. Le fait de renverser le nombre permet de placer les units en
premier dans la liste.
exemple : lentier
est reprsent par la liste l1 suivante :
5

1 NULL

l1.debut

Exercice 1
crivez une fonction rcursive int verifie_gn(liste_s l) qui teste que chaque
lment de la liste l est bien un chiffre (et non pas un nombre). La fonction renvoie si la
liste est bien un grand nombre, et sinon.
exemple : pour la liste l1 de lexemple prcdent, le rsultat de verifie_nombre(l1)
sera . Si le premier lment de nbre tait
au lieu de , alors la fonction renverrait .

Exercice 2
crivez une fonction rcursive int compte_chiffres(liste_s l) qui prend en
paramtre une liste l reprsentant un grand nombre, et compte le nombre de chiffres qui le
constituent.

TP 61

Algorithmique et programmation

1/4

nombres de grande taille

exemple : pour la liste l1 de lexemple prcdent, compte_chiffres(l1.debut) doit


retourner .
Quel est le type de rcursivit que vous avez utilis ? Calculez la complexit asymptotique
temporelle dans le pire des cas.

2 Affichage et conversion
Exercice 3
crivez une fonction void affiche_gn_it(liste_s l) qui affiche le grand nombre
reprsent par l. Pour des raisons de lisibilit, un caractre espace ' ' doit tre affich tous
les chiffres. Cette fois, vous avez le droit dutiliser compte_chiffres.
exemple : laffichage de la liste l1 prcdente donne le rsultat suivant :
1 428 635

Exercice 4
crivez une version rcursive de la mme fonction, appele cette fois void
affiche_gn_rec(liste_s l, int cpt). Pour cette fonction, vous navez plus le droit
dutiliser compte_chiffres. Le paramtre cpt sert compter le nombre de chiffres traits ;
il doit valoir lors du premier appel.
exemple : lappel affiche_gn_rec(l1,1) donne le mme affichage que ci-dessus.

Exercice 5
crivez une fonction int convertis_chaine(char* chaine, liste_s* l) qui
reoit un grand nombre reprsent sous la forme dune chane de caractres chaine, et qui la
convertir en une liste chane l. Bien sr, chaque caractre doit tre convertit en un chiffre.
La fonction retourne
en cas derreur et en cas de succs.
exemple : pour "1428635", on obtient la liste l1 de lexemple prcdent.
Remarque : on suppose que la chane ne contient que des chiffres.

3 Oprations
Exercice 6
crivez une fonction int additionne_gn(liste_s l1, liste_s l2, liste_s
*res) qui additionne les entiers reprsents par les listes l1 et l2, et place le rsultat dans la
liste res, qui est passe par adresse. La fonction doit renvoyer
en cas derreur et en cas
de succs.
exemple : pour la listes l1 des exemples prcdents et la liste l2 reprsentant la valeur
:
2

1 NULL

alors on obtient le rsultat res suivant, reprsentant la valeur


7

:
4

1 NULL

Remarque : pensez compter les retenues lors de laddition de deux chiffres.

Exercice 7
crivez une fonction rcursive int multiplie_gn_p10(liste_s *l, int p) qui
multiplie par
le grand nombre reprsent par la liste l passe en paramtre. Cette
fonction doit renvoyer
en cas derreur et en cas de succs.

TP 61

Algorithmique et programmation

2/4

nombres de grande taille

exemple : si la fonction est applique la liste l1 (donne en exemple prcdemment) et


au paramtre
, on obtient comme rsultat la liste suivante, qui reprsente le grand
nombre
:
0

1 NULL

Quel est la taille des donnes pour cette fonction ? Calculez la complexit asymptotique
temporelle dans le pire des cas.

Exercice 8
crivez la fonction rcursive int multiplie_gn_chiffre(liste_s l, int c,
liste_s *res) qui reoit en paramtres une liste l reprsentant un grand nombre, une liste
vide res, et un chiffre c (i.e.
). La fonction doit calculer le produit des valeurs
reprsentes par l et c, et placer le rsultat dans res. Cette fois, la liste l ne doit pas tre
modifie.
exemple : si on multiplie la liste prcdente l1 par , alors on obtient la liste suivante, qui
reprsente la valeur
:
0

2 NULL

Remarque : l-encore, pensez tenir compte des retenues :


retenue de
dbordement

retenues

Exercice 9
On remarque que le produit de deux nombres plusieurs chiffres peut se dcomposer en
une somme de produits de la faon suivante :


+
+

+
+

En utilisant ce principe, crivez la fonction int multiplie_gn(liste_s l1,


liste_s l2, liste_s *res) qui reoit en paramtres deux listes l1 et l2 correspondant
des grands nombres, et une liste vide res. La fonction doit calculer le produit des valeurs
reprsentes par l1 et l2, et placer le rsultat dans res. La fonction ne doit pas modifier l1
ni l2.
Remarque : vous pouvez utiliser les fonctions crites lors des exercices prcdents.
Pensez galement utiliser la fonction vide_liste_s de la bibliothque liste_s, qui
permet de supprimer tous les lments contenus dans une liste.
exemple : le produit des listes l1 par l2, utilises dans les exemples prcdents, donne la
liste suivante, correspondant la valeur
:

TP 61

Algorithmique et programmation

3/4

nombres de grande taille

2 NULL

4 Tri
Exercice 10
crivez la fonction rcursive int compare_gn(liste l1, liste l2) qui prend en
paramtres deux listes l1 et l2 reprsentant des grands nombres, et renvoie un entier
dpendant de leur comparaison :
Une valeur ngative quelconque si
;
La valeur zro si
;
Une valeur positive quelconque si
.
exemple : pour les listes l1 et l2 des exemples prcdents, on obtient une valeur
strictement positive.

Exercice 11
Soit la fonction tri suivante, qui trie un tableau dentiers de taille N :
void tri(int tab[N])
{ int i,j,temp;
for(i=1;i<N;i++)
{ temp = tab[i];
j = i-1;
while(j>=0 && tab[j]>=temp)
{ tab[j+1] = tab[j];
j--;
}
tab[j+1] = temp;
}
}

Quel est lalgorithme de tri (tudi en cours) implment par cette fonction ? Donnez, sans
la calculer (a a dj t fait en cours), sa complexit asymptotique temporelle dans le pire des
cas.
On veut appliquer le mme traitement un tableau contenant des grands nombres.
Adaptez la fonction prcdente de manire obtenir la fonction void trie_gn(liste_s
tab[N]), qui trie un tableau de N grands nombres.
exemple : pour
et les valeurs
,
,
,
et
, laffichage du tableau tri est :
1.
2.
3.
4.
5.

TP 61

1
1
2
3
9

121
428
233
649
651

111
635
222
492
105

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 62

table de symboles

Prsentation
Le but de ce TP est de crer un programme capable de lire un fichier texte et de calculer la
frquence lexicale de chaque mot quil contient. Pour cela, vous dfinirez et utiliserez une
structure de donnes spcifique appele table de symboles, en vous basant sur une liste
chane. La bibliothque liste_s est fournie avec ce sujet cet effet. Vous utiliserez
galement la bibliothque chaine, qui permet de manipuler des chanes de caractres.

1 Structure de donnes
La frquence lexicale dun mot correspond son nombre doccurrences, i.e. au nombre de
fois quil apparait dans le texte. Par exemple, le mot "vous" apparait fois dans la section
davertissement.
De faon gnrale, une table de symboles permet dassocier une valeur (ou un ensemble
de valeurs) un objet unique appel cl (ou symbole). Deux lments de la table ne peuvent
pas avoir la mme cl, par contre ils peuvent avoir des valeurs identiques.
Vous allez implmenter une version simplifie dune table de symboles en utilisant une
liste simplement chane. Dans notre cas, chaque cl correspond un mot (ex. : "vous"), et la
valeur associe est la frquence lexicale de ce mot (ex. : ).

Exercice 1
Renommez la bibliothque liste_s en liste_s_chaine et modifiez-la de manire
ladapter au problme trait ici. Vous effectuerez les modifications que vous jugerez
ncessaires sur les structures de donnes et les fonctions existantes, de manire ce quune
liste soit forme dlments contenant chacun :
Une cl prenant la forme dune chane de caractres cle ;
Une valeur entire valeur.
Crez un fichier main.c contenant une fonction main dans laquelle vous testerez ces
modifications en crant, initialisant et affichant une liste similaire lexemple ci-dessous.
exemple : affichage dune liste contenant trois cls "cle1", "cle2" et "cle3" de
valeurs respectives , et
{ cle1:2 cle2:0 cle3:5 }

Exercice 2
Crez une bibliothque table_symb. Dfinissez-y un type tabsymb pour reprsenter
une table de symboles partir dune liste. Sur le modle de ce qui a t fait en cours et en TP
avec les piles et files de donnes, ajoutez cette bibliothque une fonction cree_tabsymb
permettant de crer et dinitialiser une nouvelle table de symboles vide.

Exercice 3
Dans la bibliothque table_symb, crivez une fonction int ajoute_symb(tabsymb
*t, char *cle) qui prend en paramtre une table de symboles t et lui rajoute un lment
dont la cl est cle.

TP 62

Algorithmique et programmation

1/4

table de symboles

Si aucun lment contenant cette cl nexiste dans la liste, un nouvel lment est
insr avec une valeur de . Attention : il est essentiel dinitialiser cet lment
avec une copie de la chane de caractres cle (obtenue avec
copie_chaine_dyn, de la bibliothque chaine), et non pas avec cle ellemme.
Sil existe dj un lment avec cette cl, la valeur associe est alors simplement
incrmente.
La fonction renvoie
en cas derreur et en cas de succs. Notez que lordre des
lments dans la liste na aucune importance.
Dans la fonction main, testez cree_tabsymb et ajoute_symb : crez une table de
symboles, ajoutez-y les lments dcrits dans lexemple suivant, et affichez la table aprs
chaque insertion.
exemple : affichage obtenu aprs lajout successif des cls vous, truc, vous et mien.
Notez que laffichage est ralis dans la fonction main, et non pas dans ajoute_symb.
Ajout de
{ vous:1
Ajout de
{ mien:1

la cl "vous"
}
la cl "mien"
vous:1 }

Ajout de
{ truc:1
Ajout de
{ truc:1

la cl
vous:2
la cl
mien:1

"vous"
}
"truc"
vous:2 }

Exercice 4
Dans la bibliothque table_symb, crivez une fonction int verifie_symb(tabsymb
t, char *symb) qui prend en paramtre une table de symboles t et renvoie la valeur qui y
est associe au symbole dont la cl est symb. Si aucun lment contenant cette cl nexiste
dans la liste, la valeur renvoye est (i.e. aucune occurrence).
Dans la fonction main, testez votre fonction en lappliquant la table de lexercice
prcdent et aux cls vous et notre.
exemple : (affichage ralis dans la fonction main)
Recherche de la cl "vous" : 2 occurrence(s)
Recherche de la cl "notre" : 0 occurrence(s)

2 Analyse du texte
Exercice 5
Dans la bibliothque table_symb, crivez une fonction int analyse_texte(char
*nom_fichier, tabsymb *t) qui ouvre en lecture le fichier portant le nom
nom_fichier, lit sont contenu et ralise son analyse. Cette analyse consiste ajouter chaque
mot dans la table de symboles t. Comme dhabitude, la fonction renvoie
en cas derreur et
en cas de succs. Laccs au fichier doit obligatoirement se faire en mode format.
Testez votre fonction en lappliquant depuis la fonction main au fichier texte texte.txt
fourni avec le sujet. Il sagit dune partie de larticle de Wikipdia consacr au langage C.
Notez que ce fichier a t prtrait pour ne contenir que des lettres minuscules afin de vous
simplifier le travail. Affichez la table de symboles obtenue.
exemple : application au texte fourni avec le sujet et affichage de la table obtenue :
{ javascript:1 citer:1 peut:1 enrichi:1 extension:1 origine:1 celle:1...

3 Tri des symboles


Le texte analys contient de nombreux mots, il est difficile didentifier lesquels sont les
plus importants. On se propose dordonner la liste en fonction de leurs occurrences, i.e. en
considrant le champ valeur des lments constituant la liste.

Exercice 6
TP 62

Algorithmique et programmation

2/4

table de symboles

Dans liste_s_chaine, crivez une fonction int compare_elements(element_s


*e1, element_s *e2), qui permet de comparer les deux lments passs en paramtres.
La fonction renvoie un entier :
Ngatif si la valeur contenue dans e1 est infrieure celle de e2.
Positif si la valeur de e1 est suprieure celle de e2.
Si les deux valeurs sont gales, on compare les cls contenues dans les lments. La
fonction renvoie alors un entier :
Ngatif si la cl contenue dans e1 est place avant celle de e2 dans lordre
lexicographique ;
Positif si la cl de e1 est aprs celle de e2.
Nul si les deux cls sont exactement les mmes.
Remarque : ce dernier cas est trait pour tre exhaustif, mais dans le cadre de ce TP, la
fonction ne peut pas renvoyer puisquune cl ne peut pas apparaitre plusieurs fois dans la
table de symboles.
exemples :
Pour e1={"vous",1} et e2={"moi",4}, on obtient une valeur ngative car
1<4.
Pour e1={"vous",1} et e2={"moi",1}, on obtient une valeur positive car 1=1
et "vous">"moi".

Exercice 7
Dans liste_s_chaine, crivez une fonction element_s* etete_liste(liste_s
*l) qui tte la liste passe en paramtre, cest--dire qui en extrait le premier lment (i.e.
llment de tte). Attention, cet lment ne doit pas tre dsallou : seulement sorti de la
liste.
exemple : pour simplifier la figure, on ne reprsente que les cls des lments :
Supposons quon applique la fonction la liste suivante :
4

11

12 NULL

Alors on obtient la liste et llment suivants :

11

12 NULL

4 NULL

Remarque : on suppose que la liste nest pas vide.

Exercice 8
Dans liste_s_chaine, crivez une fonction void insere_element_dec(liste_s
*l, element_s *e) qui reoit une liste l, trie dans lordre dcroissant, et un lment e ;
et qui insre e la position approprie dans l, de manire ce que la liste reste trie aprs
cette opration.
exemple :
Considrons quon insre llment suivant dans la liste suivante :
7 NULL

12

1 NULL

1 NULL

Alors on obtient la liste suivante :


12

Exercice 9

TP 62

Algorithmique et programmation

3/4

table de symboles

Dans liste_s_chaine, crivez une fonction void trie_liste_dec(liste_s *l)


qui trie la liste passe en paramtre dans lordre croissant, en utilisant le principe du tri par
insertion vu en cours pour des tableaux.
Rappel : le principe du tri par insertion est de sparer la squence trier en deux partie :
une partie trie, qui contient initialement seulement le premier lment, et une partie nontrie, qui contient initialement tout le reste de la liste. On considre ensuite chaque lment de
la partie non-trie, et on linsre au bon endroit dans la partie trie.
Dans notre cas, on manipule des listes, et on peut donc utiliser cette structure de donnes
pour reprsenter chaque partie comme une liste spare. Attention, ici la liste trie doit ltre
dans lordre dcroissant, et non pas lordre croissant habituel du cours.
Algorithme :
Initialisation :
o Crez une nouvelle liste l2 contenant toute la liste originale l sauf le
premier lment.
o Dans la liste originale l, ne gardez que le premier lment.
o La nouvelle liste correspond la partie non-trie, la liste originale la
partie trie.
Itration : pour chaque lment de la nouvelle liste l2 :
o On extrait cet lment de l2 avec etete_liste ;
o On linsre au bon endroit dans l avec insere_element.
exemple : pour la liste du premier exercice, laffichage de la liste trie donne :
{ cle3:5 cle1:2 cle2:0 }

4 Filtrage des symboles


Utilisez la fonction trie_liste_dec pour trier la table de symboles obtenue partir du
texte. En affichant cette table trie, on peut identifier les mots les plus frquents du texte. On
saperoit alors que la plupart dentre eux sont gnriques, et nont pas un sens permettant de
caractriser le texte. Par exemple, les premiers mots obtenus sont :
{ de:36 des:17 la:14 le:13 c:13 les:12 langage:12 d:12 et:10 en:10 un:9 est:9...

Les mots du type , le, je, etc., sont appels des mots vides. On veut maintenant supprimer
ces mots de notre table de symboles, afin de ne garder que les mots intressants.

Exercice 10
Le fichier motsvides.txt fournis avec ce sujet contient une liste des principaux mots
vides de la langue franaise. crivez une fonction int filtre_mots_vides(char
*nom_fichier, tabsymb *t) qui ralise les oprations suivantes :
On ouvre le fichier nom_fichier en lecture, qui correspond une squence de
mots (i.e. dans le cas prsent : le fichier motsvides.txt).
On lit itrativement chaque mot contenu dans le fichier. Notez que chaque mot se
trouve sur une ligne distincte. Pour chaque mot :
o On cherche le mot parmi les cls de la table de symboles t.
o Si on le trouve, llment correspondant doit tre supprim de la table.
Le traitement se termine quand on a trait tous les mots contenus dans le fichier.
On ferme le fichier.
La fonction renvoie
en cas derreur, et en cas de succs. Testez votre fonction sur la
table prcdente, partir de la fonction main, et affichez la liste obtenue.
exemple : le dbut de la liste devrait correspondre :
{ langage:12 est:9 programmation:6 niveau:5 langages:5 types:4 systeme:4...

TP 62

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut
Universit
Galatasaray

TP 63

plus longue sous-squence commune

Prsentation
Le but de ce TP est dapprofondir les notions de complexit et de rcursivit, via la
dtection de plus longue squence communes. Cest aussi loccasion dintroduire le concept
de programmation dynamique.

1 Notion de PLSC
Soit
(
) une squence de lments . On appelle sous-squence de
toute squence obtenue en supprimant zro ou plusieurs lments de .
(
):
exemples : pour
) et ( ) sont des sous-squences de ;
(
) nen est pas une.
(
Soit
(
) une autre squence. On appelle sous-squence commune
toute squence qui est la fois une sous-squence de et une sous-squence de .
(
)
exemples : pour le prcdent et
( ) est, par dfinition, toujours une sous-squence commune et ;
) sont deux sous-squences communes et ;
( ) et (
) ou (
).
Ce nest pas le cas de (

et

Une plus longue sous-squence commune (PLSC)


et
est une sous-squence
(
).
commune et de longueur maximale. On la note
Remarque : et peuvent avoir plusieurs PLSC diffrentes, mais toutes ces PLSC ont la
mme longueur.
) est une
(
).
exemple : pour les et des exemples prcdents, (

2 Longueur dune PLSC


Soient
(
) et
(
suivantes :
(
Sous-squence de X :
Sous-squence de Y :
(
Longueur de
(
): .
( ) et
( ).
De plus, on pose :

) deux squences. On utilise les notations


) pour
) pour

.
.

Exercice 1
Montrez que pour

et

:
{

TP 63

Algorithmique et programmation

1/4

plus longue sous-squence commune

3 Approche nave
Exercice 2
Nous allons manipuler des squences dentiers reprsentes par des tableaux. En utilisant
le principe rcursif de lexercice prcdent, crivez la fonction int plsc1(int tab1[],
int taille1, int tab2[], int taille2). Cette fonction renvoie la taille de la plus
longue sous-squence commune aux tableaux tab1 et tab2, de tailles respectives taille1
et taille2.

Exercice 3
Donnez larbre dappels pour

) et

).

Exercice 4
Calculez la complexit temporelle de la fonction plsc1, en fonction de

et .

4 Programmation dynamique
Exercice 5
partir de la version nave de la fonction, crivez une fonction plus efficace int
plsc2(int tab1[], int taille1, int
l[P+1][Q+1]), qui calcule la matrice de taille (

tab2[],

int

taille2,

int

) telle que :

La fonction doit tre optimise de manire ne pas effectuer plusieurs fois le mme
calcul.

Exercice 6
Calculez la complexit temporelle de la fonction plsc2, en fonction de

et .

5 Construction dune PLSC


La matrice
exemple, soient
0
0 0
1 0
2 0
3 0
4
5

TP 63

0
0

obtenue grce plsc2 peut tre utilise pour construire une PLSC. Par
(
) et
(
).

0
1

0
1

0
1

1
1

1
1

2
2

2
2

2
3

Voici la matrice obtenue.

est reprsent verticalement et

Algorithmique et programmation

horizontalement.

2/4

plus longue sous-squence commune

0
0 0
1 0
2 0
3 0

0
1

0
1

0
1

1
1

0
0

1
1

2
2

2
2

0
0 0
1 0
2 0
3 0
4 0
5 0

0
0
1

0
0
1

0
0
1

0
1
1

1
1

2
2

2
2

2
3

0
0 0
1 0
2 0
3 0

0
1

0
1

0
1

1
1

0
0

1
1

2
2

2
2

2
3

0
0 0
1 0
2 0
3 0
4 0
5 0

0
0

0
0
1

0
0
1

0
1
1

2
2

2
2

2
3

0
0 0
1 0
2 0
3 0

0
1

0
1

0
1

1
1

1
1

2
2

2
2

2
3

4
5

4
5

4
5

TP 63

0
0

1
1
1

On peut observer que


et que
.
Intuitivement, on en dduit quil existe une PLSC
(
) (
).
que
(
) (
).
Do :

telle

On peut observer que


Or
et
i.e.
On en dduit que
(
).

et

.
.
)

On peut observer que


et
.
Intuitivement, on en dduit quil existe une PLSC telle que
(
) (
).
(
) ( ).
Do :

On peut observer que


et
.
Intuitivement, on en dduit quil existe une PLSC telle que
(
) ( ).
(
) ( ).
Do :
Le traitement sachve donc ici.

On obtient
,
Donc finalement

Algorithmique et programmation

et
)

.
(

).

3/4

plus longue sous-squence commune

Exercice 7
Formalisez (sans le dmontrer) un principe rcursif permettant de construire une PLSC
partir de la matrice .

Exercice 8
Grce au principe obtenu la question prcdente, crivez une fonction int
calcule_plsc(int tab1[P], int tab2[Q], int tab3[]) qui calcule une PLSC de
tab1 et tab2 et la stocke dans tab3 (on suppose que la taille de tab3 est suffisante). La
valeur renvoye par la fonction correspond la longueur des PLSC.
Pour aboutir ces rsultats, la fonction doit raliser les oprations suivantes :
1. Initialiser avec la valeur
;
2. Appeler plsc2 pour calculer ;
3. Appliquer lalgorithme dcrit ci-dessus.

TP 63

Algorithmique et programmation

4/4

Facult dingnierie et de technologie Gnie informatique

Algorithmique et programmation
Damien Berthet & Vincent Labatut

TP 64

Universit
Galatasaray

arbres binaires

Prsentation
Le but de ce TP est de manipuler des arbres binaires, dabord simples via des oprations
relativement simples, puis des arbres binaires de recherche, via une variante du tri par
insertion dj tudi pour les tableaux et listes.
Remarque : pour manipuler les arbres, vous ne devez utiliser que les fonctions
appartenant aux types abstraits dfinis en cours.
Vous aurez aussi besoin de rcuprer la fonction genere_entier contenue dans la
bibliothque tri_tab utilises lors de TP prcdents. Copiez-collez-la dans votre propre
fichier main.c.

1 Arbres binaires
Exercice 1
crivez une fonction rcursive arbre genere_arbre_complet(int h) qui gnre
alatoirement un arbre binaire complet de hauteur h, contenant des valeurs comprises entre
et
(incluses). Pour rappel, dans un arbre complet, tous les nuds sauf les feuilles possdent
le mme nombre de fils (ici : 2, puisquil sagit dun arbre binaire).
Remarque : utilisez genere_entier de tri_tab.
exemple : un arbre gnr pour h=4, affich avec affiche_arbre :
76
98
15
99
4
13

6
62
99
65
97
49
31
72

Exercice 2
crivez une fonction rcursive arbre genere_arbre_degenere(int h) qui gnre
alatoirement un arbre binaire dgnr de hauteur h, contenant des valeurs comprises entre
et
(incluses). Pour rappel, un arbre dgnr est un arbre linaire.
exemple : un arbre gnr pour h=4, affich avec affiche_arbre :
52
32
89
57

TP 64

Algorithmique et programmation

1/3

arbres binaires

Exercice 3
crivez une fonction rcursive arbre genere_arbre_aleatoire(int n) qui gnre
alatoirement un arbre binaire dont la fois les valeurs et la structure sont alatoires. Larbre
doit contenir n nuds.
Pour dterminer la structure, on utilise la mthode suivante. On tire au sort une valeur
}:
dans {
Si cest , on cre une seule branche gauche, contenant
nuds.
Si cest , on fait pareil mais pour la branche droite.
Si cest , on cre deux branches contenant chacune la moiti des
nuds
restants.
exemple : un arbre gnr pour n=18, affich avec affiche_arbre :
14
47
71
40

83

18

89

51

12

62
45
78
5
17
13
80
95
15

Exercice 4
crivez une fonction int calcule_hauteur(arbre a) qui calcule rcursivement la
hauteur dun arbre a.
exemple : pour larbre gnr dans lexercice prcdent, on obtient la valeur .

Exercice 5
crivez une fonction int compte_noeuds(arbre a) qui compte rcursivement le
nombre de nuds dans un arbre a.
exemple : pour larbre gnr dans lexercice prcdent, on obtient la valeur .

2 Arbres binaires de recherche


Il est relativement simple dimplmenter un algorithme de tri en utilisant un arbre binaire
de recherche, puisque par dfinition, cette structure de donnes stocke les valeurs de faon
ordonne.
Le tri se fait en deux tapes :
On cre un arbre vide et on y insre tous les lments trier.
On construit la squence trie en effectuant un parcours infixe de larbre.

Exercice 6
crivez une fonction void tableau_vers_arbre(int tab[N], arbre *a) qui
recopie le contenu dun tableau tab non-tri de taille N dans un arbre de recherche a, qui doit
tre initialement vide.

Exercice 7

TP 64

Algorithmique et programmation

2/3

arbres binaires

crivez une fonction rcursive void arbre_vers_tableau(arbre a, int


tab[N], int *index) qui recopie dans le tableau tab les valeurs contenues dans larbre
binaire de recherche a, en effectuant un parcours infixe. Le paramtre index est un pointeur
sur le numro de la prochaine case du tableau quil faudra remplir (index doit donc pointer
initialement sur le premier lment du tableau).

Exercice 8
crivez
une
fonction
void
tri_arbre(int
tab[N])
tableau_vers_arbre et arbre_vers_tableau pour trier le tableau tab.

qui

utilise

Remarque : dans le principe, ce tri est similaire au tri par insertion, la diffrence quon
insre dans un arbre au lieu dinsrer directement dans une structure squentielle comme un
tableau ou une liste. Par consquent, en raison des restrictions pesant sur ces arbres, les
valeurs trier doivent tre uniques (pas de rptition).

TP 64

Algorithmique et programmation

3/3