Explorer les Livres électroniques
Catégories
Explorer les Livres audio
Catégories
Explorer les Magazines
Catégories
Explorer les Documents
Catégories
3.
LES FICHIERS
sens de dfilement
x1
x2
x3
x4
xn
-|
-----f- -----------------------f+----------------
Llment courant (x3) permet, par dfinition, de dcomposer
un fichier en deux sous-fichiers : f = f- || f+
O f- est le sous-fichier dj lu et f+ est le sous-fichier qui reste
lire. Llment courant est le premier lment de f+.
Dans cet exemple : f- = <x1, x2>, f+ = <x3,,xn>, llment
courant est x4.
Notation fest dfinie par : f- = f--|| val.
fest le fichier f- avant excution de laction : lire(f,val)
3.2.1.
Dclaration.
anne 2008
34
while( !feof(f)){
fscanf(f, %s %s\n , nom, prenom) ;
}
Consulter ce programme qui lit et affiche le contenu du fichier
C:\AUTOEXEC.BAT.
programme ch3_1.c
Dans une chane de caractres constante, il faut indiquer le
symbole\ par \\ pour quil ne soit pas confondu avec le dbut
dune squence dchappement (par exemple \n, \t).
Tableau 1 : Rsum sur fichier caractre et texte
Action
ouverture en
criture
ouverture en
lecture
fermeture
fct finfichier
criture
Algorithme
ouvrir <nom> en
criture
ouvrir <nom> en
lecture
fermer <nom>
finfichier <nom>
crire<nom>:<var>
lecture
lire<nom>:<var>
C
f=fopen(nom, w)
f=fopen(nom,r)
fclose(f)
feof(f)
fprintf(f,,adr)
fputc
fscanf(f,,adr)
c=getc(f)
anne 2008
35
f+ = <>
f- = f, lexcution de linstruction : retour m ;
permet de terminer lalgorithme (maxi f, maxi f).
f+ <>
On lit llment courant : lire f : c ;
// m f-, m f-, f- = f- || <c>
On compare c avec m. On a de nouveau deux cas :
** m c
On peut donc crire mf-||<c> mf-, mf-.
** m < c
Lexcution de linstruction : m = c ;
permet lcriture mf- || <c> mf-, mfOn a donc une itration compose dune seule condition portant
sur la fin de fichier.
Initialisation : on suppose que le fichier f nest pas vide ; on
donne alors m la valeur x1, premire valeur du fichier f :
Ouvrir(f, en lecture) ;
lire (f, m) ;
// m f-, m f- est alors un invariant.
Le raisonnement est rsum par le schma suivant :
Hypothse : m f-, m f f+ = <>
retour m
m f-, m f- *
f+ <>
.
=> lire (f, c) ;
=> m f-, m f-, f- = f- || <c>
>> m c
H
>> m < c
=> m = c ;
H
Itration : tantque(non fdf(f))
Initialisation : ouvrir (f, en lecture) ;
lire (f, m); H
Lalgorithme est alors :
programme ch3_3.c
Pour les algorithmes prcdents, litration est toujours de la
forme :
: ouvrir (f, en lecture) ;
.
tantque(non fdf(f)){
lire (f, c) ;
traiter (c) ;
}
O traiter est une fonction quelconque agissant ou non sur le
contenu de la variable c. A chaque excution de laction lire (f,
c); le nombre dlments de f+ diminue de un. En un nombre
anne 2008
36
anne 2008
37
val f
f+ <>
*
*
precedent = c ;
lire(f, c) ; H
Itration : tantque(non fdf(f) et (precedent c))
Initialisation : ouvrir (f, en lecture);
f+ = <>
*
f+ <>
lire(f, precedent) ;
lire(f, c) ;
infer
vrai
vrai
faux
faux
vrai
faux
faux
rsultat : accest
f- tri
. >> f+ = <>
>> f+ <>
Rakotoasimbahoaka Cyprien
Hypothse : g = f f+ = <>
g =f
Robert
anne 2008
f+ <>
lire (f, c) ;
g = f-, c = Df-
*
*
38
f+ <>
lire (f, c) ;
>> pair(c)
crire(fpair, c) ;
>> pair(c)
crire (fimpair, c) ; H
Itration : tantque(non fdf(f))
Initialisation : ouvrir (f, en lecture);
ouvrir (fpair, en criture) ;
ouvrir (fimpair, en criture)
programme ch3_10.c
anne 2008
39
c val
Programme
ch3_15.c
Itration : tantque(non
fdf(f)et(cval))
insertion
dans un fichier tri.
Initialisation : d)
ouvrir
(f, en lecture);
en criture)
lire(f, c) ; dans
Onouvrir
veut(g,ajouter
un ;lment
un fichier tri f de
sorte
valf-, que
g=f-, c=Dftelle
lon obtienne un fichier tri g.
crire(g,
c) ;
H
Lajout
est toujours
possible.
Exemple : f = <c, f, g, m>.
insertion de a <a, c, f, g, m>
*
*
H
*
crire(g, valinsert) ;
f+ <>
lire(f, c)
Le dbut de lalgorithme :
{tc;
ouvrir (f, en lecture) ; ouvrir(g, en criture) ;
si(fdf(f)) crire(g, valinsert) ;
sinon
{ lire(f, c) ;
tantque(non fdf(f) et (c < valinsert)){
crire(g, c) ; lire(f, c) ;
}
// fdf(f) v c valinsert
}
}
Tableau 6 : tableau de sortie
fdf(f)
vrai
vrai
faux
c valinsert
vrai
faux
vrai
faux
faux
Rsultat
crire(g,valinsert) ; crire(g,c) ;
crire(g,c) ; crire(g,valinsert) ;
crire(g,valinsert) ; crire(g,c) ;
copier le reste de f
impossible (tantque)
Programme ch3_16.c
3.4.2.2. Suppression dun lment dans un fichier
On peut supprimer le kime lment (suppression par position)
ou supprimer une valeur (suppression associative). Dans le cas
dune suppression associative le fichier peut tre tri, ce qui
permet d
acclrer lalgorithme au cas o llment que lon veut
supprimer est absent du fichier.
anne 2008
40
val f
crire(g, c) ;
val g, g = f-, c = Df-
lire(f, c) ;
H
Itration : tantque(non fdf(f)et(cval))
Initialisation: ouvrir (f, en lecture); ouvrir (g, en criture);
val g, g = f-;
lire(f, c)
c = val
vrai
faux
vrai
faux
faux
rsultat
val = Df, g=f ; possible = 1
val f ; possible = 0 ;
possible = 1; suppression de val
copie du reste de f
impossible (tantque)
anne 2008
41
fdf(f)
vrai
vrai
faux
faux
A
b
c
et liste+ = (a, b, c, d). On notera :
liste2
p- est ambigu car on ne sait pas si cest
p-liste1 = (a, b) ou p-liste2 = (a, b).
4.1.2. Algorithme de cration dune liste chane.
Crer une liste chane qui est la reprsentation de (a, b).
Dclaration : type structure.
structure cellule { t info ;
structure cellule * suivant ;
};
O t est un type simple, vecteur, structure,et on peut dclarer
une variable liste :
structure cellule*liste; //liste est de type structure cellule* ou
bien pour viter dcrire chaque fois le type structure cellule
*, on dfinit dabord un type synonyme de structure cellule * :
type structure cellule *pointeur ; /* pointeur est un type
synonyme de structure cellule *. */
On peut dclarer une variable de type pointeur :
pointeur liste, p ; /* p, liste sont de type pointeur. Ce type
pointeur sera utilis dans la suite du cours.
anne 2008
42
p->
<-------------
info
suivant
anne 2008
43
liste+ = <>
sa longueur est alors gale zro.
retour 0 ; termin
*
liste+ <>
elle est donc compose dune cellule (le
premier lment) chane la sous-liste liste->suivant+. La
longueur de la liste est donc gale un plus la longueur de la liste
liste->suivant+.
retour (1 + long (liste->suivant)); H
Algorithme : nombre dlment en algorithme rcursif.
Programme ch4_11.c
liste+ = <>
liste+ <>
On notera quil faut toujours tester dabord la liste vide afin quon
puisse ensuite, dans le cas contraire, utiliser les notations liste->info et
liste->suivant (qui ne sont dfinies que si liste nil).
Algorithme : nombre doccurrences dun lment dans une liste,
schma rcursif.
Programme ch4_13.c
4.1.5.3. Algorithmes daccs dans une liste.
On distingue deux sortes daccs: accs par position ou accs
associatif.
a) Algorithme daccs par position
- schma itratif
On utilise le mme algorithme que celui donn sur les fichiers
squentiels.
Algorithme : accs par position un lment dans une liste.
Programme ch4_14.c
- schma rcursif
Le raisonnement est fond sur la constatation suivante : chercher le
kime (k>1) lment revient chercher le k-1ime lment dans liste>suivant+ comme indiqu dans le schma suivant :
liste
(1)
(2)
(k-1) (k)
(n)
liste->suivant
(1)
(k-2)
(k-1)
(n-1)
Le raisonnement est :
liste+ = <>
liste+ <>
>> k = 1
>> k 1
anne 2008
44
p=p->suivant ; H
Itration : tantque ((p nil) et (p->info val))On rappelle que p>info nest dfinie que si pnil. On utilise une variable boolenne
trouve.
Initialisation: trouve = faux ;
point devra contenir ladresse de la cellule contenant la valeur de la premire occurrence de la valeur val
si elle existe dans liste+,
liste+ = <>
la valeur val nest pas prsente dans liste+
retour nil ;.*
liste+ <>
>> liste->info < val
on doit chercher la premire occurrence de val
dans liste->suivant+.
retour point (liste->suivant, val)
>>liste->info > val
la valeur val nest pas dans la liste
retour nil ;*
>> liste-> info == val
le cellule dadresse liste contient la premire
occurrence de val.
retour liste ;..*
Algorithme : accs associatif dans une liste trie, schma
rcursif.
Programme ch4_18.c
d) Algorithme de recherche dune sous-liste dans une liste.
On recherche un ensemble de valeurs dans une liste. On peut
formaliser le problme comme suit :
Soient :
anne 2008
45
p=p->suivant ; H
Itration : tantque ((non prefixe(p, sliste)) et (p nil))
Initialisation : il suffit de commencer au dbut de la liste H
Algorithme : recherche dune sous-liste dans une liste
Programme ch4_19.c
b) schma rcursif
On souhaite crire une fonction dont len-tte suit :
entier recherchesliste (pointeur liste, pointeur sliste)
//spcification(sliste+ nil)(recherchesliste = (liste+ =
//la+ || sliste+ || lb+))
Le raisonnement :
liste+ = <>
sliste+ nest pas une sous-liste de liste+
.*
liste+ <>
>> sliste+ est un prfixe de liste+
sliste+ est une sous-liste de liste+.
..*
>>sliste+ nest pas un prfixe de liste+
On cherche si sliste+ est un prfixe de la liste
liste->suivant+.
retour retour recherchesliste(liste->sui-vant,
sliste) ;
Algorithme : recherche dune sous-liste dans une liste, schma
rcursif.
Programme ch4_20.c
c) criture de la fonction prefixe.
- schma itratif.
Il faut effectuer un parcours simultan de deux sous-listes en
comparant les lments situs la mme position.
Raisonnement par rcurrence :
Hypothse : p- == sp-.
sp+ = <>
liste+ = <>
retour 0 ;.*
liste+ <>
>> liste->info sliste->info
retour 0 ;....*
>>liste->info==sliste->info
>>>sliste->suivant == nil
retour 1 ; ..*
>>>sliste->suivant nil
Cyprien Robert
anne 2008
46
Le raisonnement est :
(b)
(a)
lment insrer
p
Il faut dabord crer la cellule dadresse p. Ensuite, le
champ information reoit la valeur de llment, pour
terminer par la ralisation des deux liaisons (a) et (b) dans
cet ordre. Les lments suivants sont dcals
automatiquement dune position.
Algorithme : insertion dun lment en tte dune liste.
Programme ch4_23.c
b) Algorithme dinsertion dun lment en fin de liste.
- schma itratif.
Si la liste est vide, on est ramen une insertion en tte.
Dans le cas gnral, la liste nest pas vide.
liste
der
liste+ = nil
On insre llment.
retour (insertete (*liste, elem)) ;*
liste nil)
retour inserfin ((*liste)->suivant, elem)
liste
(b)
lment insrer
(1)
(k-1)
(a)
(b)
p
Aprs avoir cr une cellule dadresse p contenant
linformation elem, on doit effectuer les liaisons (a) et
(b). Pour pouvoir effectuer la liaison (b), il faut connatre
ladresse der de la dernire cellule.
Disposant de la fonction dernier dont len-tte est :
pointeur dernier (pointeur liste)
//spcification (liste nil) (dernier = der, liste+ = //
der- || der+, der->suivant = nil).
Algorithme : insertion dun lment en fin de liste,
schma itratif.
Programme ch4_24.c
Algorithme : insertion en fin de liste, schma itratif 2.
Programme ch4_25.c
c) Ecriture de la fonction dernier.
- schma itratif.
On effectue un parcours de tous les lments de la liste en
prservant chaque fois ladresse de la cellule
prcdente.
Raisonnement par rcurrence.
Hypothse : precedent = Dp-.
O Dp- : adresse de la dernire cellule de p-.
p+ = <>
cellule de la liste.*
p+ <>
precedentque
= ples
; p=p->suivant
;dans
H linitialisation sont
On constate
deux actions
est au moins effectue une fois (la liste nest pas vide).
Algorithme : la fonction dernier
Programme ch4_26.c
- schma rcursif.
(k)
(k+1)
(n)
(n+1)
(a)
lment insrer
(p)
(k)
- schma itratif.
Linsertion dun lment la kime place consiste crer les
liaisons (a) et (b) dans cet ordre. Les lments suivants sont
automatiquement dcals dune position sans quon ait le
dplacer. Pour raliser la liaison (b), il faut connatre ladresse
de la cellule prcdente (la k-1me). Linsertion nest possible
que si k [1..n+1] o n est le nombre dlments de la liste. Il
faudra prvoir linsertion en tte (k==1) car elle modifie
ladresse de la liste. On utilisera la fonction pointk pour
dterminer ladresse de la k-1me cellule.
Algorithme : insertion dun lment la kime place, schma
itartif.
Programme ch4_29.c
Cet algorithme est qualifi ditratif bien quil ny ait pas
ditration visible. Celle-ci se trouve dans la version itrative
de la fonction pointk. On devrait plutt qualifier ce schma de
non rcursif.
Deuxime version : on peut galement effectuer le
raisonnement : insrer un lment la kime place revient
insrer cet lment en tte de la liste dont le pointeur de tte se
trouve dans le champ adresse de la k-1ime cellule (insertion en
tte de la liste qui commence la kime cellule) On peut
galement constater que lexcution des actions /*1*/, /*2*/,
/*3*/, /*4*/ de lalgorithme ci-dessus correspond lexcution
de laction insertete pour la liste precedent->suivant+ en
crivant la place de ces actions laction insertete
((*precedent)->suivant, elem) ;
- schma rcursif.
anne 2008
47
k=1
On effectue une insertion en tte de liste+
retour (insertete (*liste, elem)) ; ..*
k1
>>liste+ est vide
linsertion est impossible....*
>>liste+ nest vide
insertk ((*liste)->suivant, k-1, elem, *possible)
Cas particuliers :
(b)
(a)
lment insrer
p
- schma non rcursif de la fonction point.
On utilise la fonction point pour connatre ladresse
de la cellule contenant la premire occurrence de la
valeur val. Ensuite, si cette valeur existe, il suffit
deffectuer une insertion en tte de la liste dont le
pointeur se trouve dans le champ adresse de la
cellule qui contient val.
Algorithme : insertion de elem aprs la premire
occurrence de val, schma non rcursif.
Programme ch4_31.c
- schma rcursif.
On souhaite crire la fonction insert sous-forme
rcursive
Le raisonnement :
liste+ = <>
linsertion est impossible car val liste+...*
liste <>
>>liste->info==val
on effectue linsertion en tte liste->suivant
insertete((*liste)->suivant, elem)..*
>>liste->infoval
insert(liste->suivant, val, elem)
Algorithme : insertion de elem aprs la premire
occur-rence de val, schma rcursif.
Programme ch4_32.c
f) Algorithme dinsertion dans une liste trie
On considre que la liste est la concatnation de
deux sous-listes la et lb telle : liste+ =la+||lb+ et
la+<elemlb+
Nous avons mis lgalit droite afin de minimiser
le temps de parcours.
liste+ = <>
on effectue linsertion en tte de liste+
insertete (*liste, elem)...*
liste <>
>>liste->info<elem
liste->info appartient la+
insertri ((*liste)->suivant, elem) ;
>>liste->infoelem
on est positionn sur le 1er lment de lb+.
insertete((*liste), elem) ; *
liste
preced
|______________________|
p- < elem, preced = DpHypothse : p- < elem, preced = Dp-.
O Dp- : adresse de la dernire cellule de p-.
p+ = <>
insrer en fin de liste (en tte de la liste
preced->suivant)
insertete(*(preced)->suivant, liste)*
p+ <>
>> p->info < elem
la cellule dadresse p appartient la+.
preced = p ; p=p->suivant ; H
>> p->info elem
on insre elem en tte de lb+.
insertete (preced->suivant, elem) ; *
Itration : tantque ((p nil) et (elem > (p->info))
Utiliser une variable boolenne : super.
Initialisation :
On a deux cas particuliers :
liste+ = <>, il faut effectuer une insertion en tte de
liste+ : insertete (*liste, elem) ;
liste+ <>, elem liste->info, on effectue une
insertion en tte de liste+ : insertete (*liste, elem) ;
Ces deux cas particuliers tant traits, on ralise
linitialisation preced = liste ;
p = liste->suivant
H
anne 2008
48
schma :
liste precedent
ptk
lment
supprimer
sliste
(2)
(1)
Il faut chercher ladresse du dernier lment de la sousliste sliste+ afin dtablir la liaison (1). Linsertion peut
seffectuer par position ou par rapport loccurrence
dune valeur. Nous choisissons le cas de laccs associatif aprs la premire occurrence de la valeur val.
Algorithme : insertion dune sous-liste dans une liste.
Programme ch4_35.c
4.1.6.2. Algorithme de suppression dun lment dans
une liste.
On a le cas particulier de suppression du premier lment
qui a pour consquence de modifier ladresse de la liste.
Dans le cas gnral, il suffit de modifier le contenu dun
pointeur.
Schma :
liste
Elment
supprimer
Llment supprimer peut tre dtermine par sa
position ou par sa va leur (suppression associative).
a) Algorithme de suppression du premier lment.
On suppose que la liste nest pas vide.
Schma :
liste
Elment
supprimer
On suppose quon na plus besoin de llment et quon
rend la cellule au rservoir de cellules. Il faut donc
prserver ladresse de la tte de liste avant deffectuer la
modification de cette adresse.
Algorithme : suppression du 1er lment.
Programme ch4_36.c
b) Algorithme de suppression par position.
Supprimer le kime lment.
- schma itratif.
Il faut dterminer ladresse precedent de la cellule qui
prcde celle que lon veut supprimer : cest--dire
ladresse de la k-1ime cellule qui sera obtenue par la
fonction pointk. Ensuite si le kime cellule existe, on
modifie la valeur dadresse precedent.
liste+ = <>
la suppression est impossible. car val liste+. On
excute *possible = 0 ;...*
liste <>
>>k==1
on effectue la suppression en tte liste.
*possible = 1 ; supptete(*liste) ;..*
>>k1
supprimek((*liste)->suivant, k-1, *possible) ;
Algorithme : suppression du kime lment, schma rcursif.
Programme ch4_38.c
Si k a une valeur ngative ou nulle. Lalgorithme est correct
mais demande un parcours complet de la liste. Il est alors
souhaitable lappel de sassurer que k est positif afin dviter
ce parcours inutile.
b) Algorithme de suppression associative.
Supprimer la premire occurrence de val de la liste. Il faut
dfinir une variable boolenne possible qui nous permettra de
savoir si cette suppression a t ralise ou non.
- schma rcursif. On souhaite crire une fonction :
vide suppval (pointeur *liste, t avl, entier *possible)
//spcification ()((possible, suppression de la 1re //
occurrence de val) v (possible, suppression im-// possible))
liste+ = <>
la suppression est impossible. car val liste+. On
excute *possible = 0 ;.*
liste <>
>>liste->info==val
on effectue la suppression en tte liste.
*possible = 1 ; supptete(*liste) ;..*
>>liste->infoval
suppval((*liste)->suivant, val, *possible) ;
Algorithme : suppression associative, schma rcursif.
Programme ch4_39.c
- schma itratif : aprs avoir trait le cas de suppression du
premier lment, on utilise le raisonnement suivant dans le cas
gnral : pour supprimer la cellule contenant la premire
occurrence de val, il faut connatre ladresse de la cellule
prcdente. Pour dterminer cette adresse, on peut, utiliser une
variable auxiliaire precedent et la variable liste ou utiliser liste
et liste->suivant.
Algorithme : suppression associative de la premire occurrence
de val, schma itratif.
anne 2008
49