Skip to content
Snippets Groups Projects
Verified Commit 8b01f245 authored by orestis.malaspin's avatar orestis.malaspin
Browse files
parents 1805b762 9bc73375
No related branches found
No related tags found
No related merge requests found
# Algorithmique et structures de données 2019-20
Contenu du cours 5 du 16.10.2019
******
## Type composé : `struct`
- **Exemple des fractions**
- On considère une structure pour stocker des fractions :
```C
struct _fraction {
int num;
int den;
} fraction;
```
- On aimerait aussi définir les opérations arithmétiques associées ou utilitaires :
```C
void print(fraction frac);
int pgcd(int n,int m);
void reduire(fraction* frac);
fraction fraction_build(int num,int den);
fraction add(fraction frac1,fraction frac2);
fraction add1(int n,fraction frac);
fraction add2(fraction frac,int n);
void add_inplace(fraction* frac1,fraction frac2);
fraction sub(fraction frac1,fraction frac2);
fraction sub1(int n,fraction frac);
fraction sub2(fraction frac,int n);
void sub_inplace(fraction* frac1,fraction frac2);
fraction mult(fraction frac1,fraction frac2);
fraction mult1(int n,fraction frac);
fraction mult2(fraction frac,int n);
void mult_inplace(fraction* frac1,fraction frac2);
fraction divise(fraction frac1,fraction frac2);
fraction divise1(int n,fraction frac);
fraction divise2(fraction frac,int n);
void divise_inplace(fraction* frac1,fraction frac2);
fraction puiss(fraction frac,int n);
float reel(fraction frac);
```
- Quelques implémentations de fonctions
```C
void reduire(fraction* frac) {
if (0 == frac­>num) {
frac­>den = 1;
} else {
int gcd = pgcd(abs(frac­>num),frac­>den);
frac­>num /= gcd;
frac­>den /= gcd;
}
}
fraction fraction_build(int num,int den) {
assert(den != 0);
int sign = den/abs(den);
fraction res = {sign*num,sign*den};
reduire(&res);
return res;
}
fraction add(fraction frac1,fraction frac2) {
return fraction_build(
frac1.num*frac2.den+frac1.den*frac2.num,
frac1.den*frac2.den
);
}
fraction add1(int n,fraction frac) {
return add(fraction_build(n,1),frac);
}
fraction add2(fraction frac,int n,) {
return add1(n,frac);
}
void add_inplace(fraction* frac1,fraction frac2) {
*frac1 = add(*frac1,frac2);
}
fraction puiss(fraction frac,int n) {
fraction prod = fraction_build(1,1);
for (int i=1;i<=abs(n);i++) {
prod = mult(prod,frac);
}
if (n < 0) {
prod = divise1(1,prod);
}
return prod;
}
```
- **Exemple des chaînes de caractères**
- On peut définir un type pour les chaînes de caractères en stockant la longueur effective de la chaîne, c'est-à-dire la première occurrence du caractère `\0`
```C
struct _chaine {
char* str;
int len;
} chaine;
```
- Quelques implémentations de fonctions
```C
chaine chaine_build(char* phrase) {
chaine ch;
ch.len = length(phrase);
ch.str = malloc((ch.len+1)*sizeof(char));
for (int i=0;i<ch.len;i++) {
ch.str[i] = phrase[i];
}
return ch;
}
chaine deep_copy(chaine ch) {
return chaine_build(ch.str);
}
// Dangereux, car plusieurs pointeurs
// sur le même tableau de caractères !!!
chaine shallow_copy(chaine ch) {
chaine cpy;
cpy.len = ch.len;
cpy.str = ch.str;
return cpy;
}
// Si plusieurs pointeurs sur même tableau de caractères,
// alors autres pointeurs dessus ne seront pas mis à NULL
void chaine_free(chaine* ch) {
if (NULL != ch­>str)
free(ch­>str);
ch­>str = NULL;
}
ch­>len = -­1;
}
```
- Illustration
## Récursivité
- Exemple de la factorielle : n ! = n·(n-1)·(n-2)·... ·3·2·1 = n·(n-1) !
Donc fact(n) = n·fact(n-1) (récursivité)
et fact(1) = 1 (condition d'arrêt)
```C
int fact(int n) {
if (n > 1) {
return n*fact(n­1);
} else {
return 1;
}
}
void main() {
int f = fact(4);
}
```
- Exemple du PGCD
Algorithme d'Euclide pour le PGCD de 42 et 27
> 42 = 27·1 + 15
> 27 = 15·1 + 12
> 15 = 12·1 + 3
> 12 = 3·4 + 0
PGCD(42,27)=PGCD(27,15)=PGCD(15,12)=PGCD(12,3)=3
```C
int pgcd(int n,int m) {
if (n%m > 0) {
return pgcd(m,n%m);
} else {
return m;
}
}
```
- Exemple de l'écriture binaire
```C
void binaire(int n) {
printf("%d",n%2);
if (n/2 != 0) {
binaire(n/2);
} else {
printf("\n");
}
// printf("%d",n%2);
}
Binaire(13); // affiche 1 0 1 1 puis un retour à la ligne`
```
> > > $\hspace*{36mm} 2^0 2^1 2^2 2^3$
- Que se passe-t-il si on décommente le deuxième `printf` ?
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment