Sie sind auf Seite 1von 4

Exercices d’algorithmique : Correction

Une bonne façon de comprendre les algorithmes présentés dans la suite est d’essayer, avec
de petites valeurs pour les paramètres, de simuler l’exécution du programme. Cela permet de
comprendre à quoi servent les variables du programme, en observant les différentes valeurs prises
durant une exécution.

1 Suite de Fibonacci
Voici deux façons de calculer la suite de les éléments de la suite de Fibonacci. La première
remplit un tableau T contenant toutes les valeurs de la suite, la seconde n’utilise que deux
variables a (pour stocker fn−1 ) et b (pour fn ).
function res = f ibo(n) function b = f ibo0 (n)
T = zeros(1, n);
T (1) = 1; a = 1;
T (2) = 1; b = 1;
for i = 3 : n for i = 3 : n
c = a + b;
T (i) = T (i − 1) + T (i − 2); a = b;
b = c;
end end
res = T (n);
Pourquoi ces algorithmes sont-ils corrects ?
Dans f ibo0 par exemple, on peut prouver par récurrence qu’à la fin d’une boucle i, la variable
a contient fi−1 et la variable b contient fi . Pour les cas de bases n = 1 et n = 2, b contient fn
avant la boucle.

2 Nombres binaires
L’algorithme suivant renvoie un tableau de deux cases, la première contient le quotient et
la seconde le reste de la division euclidienne.
function T = div euclide(a, b)
q = 0;
r = a;
% commentaire ici
while r > b
q = q + 1;
r = r − b;
% et ici aussi
end
T (1) = q;
T (2) = r;

1
Cet algorithme renvoie bien le quotient et le reste de la division euclidienne de a par b.
En effet, on peut prouver (par récurrence encore) qu’au niveau des commentaires, l’équation
a = b ∗ q + r est vérifiée. Or l’algorithme ne sort de la boucle while que si r est plus petit que
b, la deuxième condition pour la division euclidienne est alors vérifiée.

Il existe plusieurs façons de traduire un nombre binaire décrit par un X


tableau de 0 et de 1
en un nombre décimal. Une première façon consiste à simuler la formule ai ∗ 2(i−1) .
16i6n

function d = bin to dec(B)


n = length(B);
d = 0;
for i = 1 : n
d = d + B(i) ∗ 2(i−1) ;
end

Soit n un nombre, la suite des divisions euclidiennes par 2 donne :

n = q1 ∗ 2 + a1
q1 = q2 ∗ 2 + a2
q2 = q3 ∗ 2 + a3
...
qn−2 = qn−1 ∗ 2 + an−1
qn−1 = 0∗2 + an

avec les ai < 2, d’où

n = (((. . . (an ∗ 2 + an−1 ) ∗ 2 + . . .) ∗ 2 + a3 ) ∗ 2 + a2 ) ∗ 2 + a1

Cela inspire un autre algorithme n’utilisant pas la fonction puissance :

function d = bin to dec0 (B)


n = length(B);
d = 0;
for i = n : 1
d = d ∗ 2 + B(i);
end

En développant la précédente égalité, on obtient

n = an ∗ 2n−1 + an ∗ 2n−1 + . . . + a3 ∗ 22 + a2 ∗ 21 + a1 ∗ 20

et donc la formule voulue pour la décomposition en binaire de n. La suite de divisions eucli-


diennes par 2 nous donne donc une méthode pour l’algorithme traduisant un nombre dans sa
représentation binaire.
function B = dec to bin(d)
i = 1;
T = [ a 0 ];
while T (1) > 0
T = div euclide(q, 2);
B(i) = T (2);
i = i + 1;
end

2
Enfin, il est possible de sommer 2 nombres binaires contenus dans des tableaux de même
taille n dans un tableau de taille n + 1.
function B = somme bin(B1, B2)
n = length(B1);
% ret correspond à la retenue
ret = 0;
for i = 1 : n
% On somme chaque colonne sans oublier la retenue.
% La division euclidienne nous permet d’obtenir
% le chiffre et la retenue qui est propagée.
T = div euclide(B1(i) + B2(i) + ret, 2)
B(i) = T (2);
ret = T (1);
end
B(n + 1) = ret;

3 Maximum et Tri
Les fonctions calculant le maximum (ou l’indice du maximum) d’un tableau sont simples :
il suffit de parcourir tout le tableau et, à chaque nouvelle plus grande valeur, mettre à jour le
résultat.
function m = max(T ) function j = max indice(T )
n = length(T ); n = length(T );
m = T (1); j = 1;
for i = 2 : n for i = 2 : n
if m < T (i) if T (j) < T (i)
m = T (i) j=i
end end
end end
La fonction de tri utilise une fonction qui échange deux valeurs d’un tableau. L’algorithme
consiste à trouver le plus nombre, et à l’échanger avec le premier élément du tableau, puis de
recommencer sur le reste du tableau.
function T = tri(T )
% On cherche le i-ème plus petit
% dans le reste du tableau. function T = echange(T, i, j)
for i = 1 : (n − 1) temp = T (i);
pp = i; T (i) = T (j);
for j = (i + 1) : n T (j) = temp;
if T (j) < T (pp);
pp = j
end
end
% pp est l’indice du plus petit
% élément du tableau [T(i) ... T(n)].
T = echange(T, i, pp);
% le tableau [T(1) ... T(i)]
% est maintenant trié.
end
end

3
Deux algorithmes cherchant un nombre dans un tableau (si l’élément est présent, on renvoie
son indice, sinon on renvoie −1) sont présentés en parallèle. Le premier cherche dans un tableau
non trié en parcourant tous les éléments. On s’arrête si l’élément a été trouvé ou si tous les
éléments ont été parcourus. Le deuxième cherche de façon dichotomique : g et d représente les
bornes gauche et droite du sous-tableau où x est cherché. A chaque étape, on regarde le milieu
de cet intervalle, en le comparant avec x on sait alors dans quelle partie du tableau chercher.

function p = present(T, x) function b = present tri(T, x)


g = 1;
d = length(T );
i = 1; i = f loor((g + d)/2);
while T (i) = x && i <= n while T (i) = x && g <= d
if x < T (i)
d = i − 1;
else
g = i + 1;
end
i = i + 1; i = f loor((g + d)/2);
end end
if i > n if g > d
p = −1; p = −1;
else else
p = i; p = i;
end end

Les tests à la fin déterminent de quelle façon est-on sorti de la boucle while : dans un cas x
n’est pas présent (on renvoie −1), dans l’autre on connait son indice.

Das könnte Ihnen auch gefallen