Un des plus anciens algorithmes connus, dû à Euclide, permet de calculer
le plus grand commun diviseur de deux entiers a et b, par itération.
L'algorithme utilise deux variables x et y,
initialisées aux valeurs a et b, puis opère itérativement sur ces
variables. L'idée de la transformation est de maintenir
l'invariant et de s'arrêter quand
x=y auquel cas,
. Euclide savait que si x>y,
et que si y>x,
. D'où l'itération suivante, qu'on peut décrire ainsi en français
: << tant que x et y sont différents, soustraire le plus petit du
plus grand >> :
while (x != y) {
if (x > y) {
x = x-y;
} else {
y = y-x;
}
}
Contrairement au for de l'exemple précédent, il n'est pas
évident que cette boucle
termine , c'est-à-dire qu'il n'y ait
qu'un nombre fini d'itérations. En effet si a ou b est
, la
boucle ne termine pas. Supposons que a>0 et b>0 ; après
initialisation, on a donc x>0 et y>0; à chaque itération, si
,
décroît strictement, mais reste strictement positif. Il
y a donc au plus
itérations avant que la condition ne
devienne fausse, c'est-à-dire que x=y. Ce n'est pas très efficace.
Tout en conservant le même invariant , on peut choisir
d'autres transformations de x et y de sorte que la
boucle termine en moins d'itérations ; c'est l'algorithme d'Euclide,
dans sa version moderne, où l'on remplace la soustraction par le calcul
du reste par division entière (opérateur
%
), en utilisant
l'identité ; voici ce que donne
directement ce remplacement :
while (x != y) {
if (x > y) {
x = x%y;
} else {
y = y%x;
}
}
Comme , les tests peuvent être éliminés en faisant en
sorte que la valeur de x soit supérieure à celle de y.
int pgcd(int x, int y) {
while (y > 0) {
int t = x%y;
x = y;
y = t;
}
return x;
}
Rappelons que les arguments étant passés par valeur, les affectations
aux paramètres x et y ne modifient que des variables
locales et en aucune façon les arguments eux-mêmes.
Il existe également une itération do ... while (...);, plus rarement utilisée, qui exécute au moins une fois son corps et s'arrête quand la condition n'est plus vérifiée (on veillera à ne pas oublier le << ; >> final). Un exemple sera donné ultérieurement.