420-201-RE – Formes d'alternatives

Pour les alternatives composites, on trouve deux grandes familles de formes générales, soit la forme imbriquée et la forme empilée. Les deux ont des avantages et des inconvénients.

Nous allons examiner chacune de ces formes à l'aide d'un même problème, soit trouver le plus petit de trois nombres.

Forme imbriquée

Résoudre ce problème avec une alternative de forme imbriquée signifie que nous visons à :

Dans l'exemple qui suit, la première décision – l'alternative principale, comparant x et y – permet d'éliminer une des deux valeurs candidates (x ou y, selon le cas), puis l'alternative imbriquée dans chaque branche permet de choisir parmi les deux valeurs restantes.

En pseudocodeEn code C#
Lire x
Lire y
Lire z
Si x < y Alors
   Si x < z Alors
      plusPetit ← x
   Sinon
      plusPetit ← z
Sinon
   Si y < z Alors
      plusPetit ← y
   Sinon
      plusPetit ← z
Écrire plusPetit
// ...
static void Main(string []args)
{
   int x,
       y,
       z;
   int plusPetit;
   x = int.Parse(Console.ReadLine());
   y = int.Parse(Console.ReadLine());
   z = int.Parse(Console.ReadLine());
   if (x < y)
   {
      if (x < z)
      {
         plusPetit = x;
      }
      else
      {
         plusPetit = z;
      }
   }
   else
   {
      if (y < z)
      {
         plusPetit = y;
      }
      else
      {
         plusPetit = z;
      }
   }
   Console.WriteLine(plusPetit);
}
// ...

Cette forme a la qualité importante d'exiger le même nombre de tests de conditions peu importe le chemin suivi par l'exécution du programme. En effet, peu importe le chemin suivi ici, le programme nécessitera sept opérations (trois si on omet les entrées et les sorties).

Elle a par contre le gros défaut de se généraliser difficilement à un plus grand nombre de variables. Par exemple, avec quatre variables, on a :

En pseudocodeEn code C#
Lire x
Lire y
Lire z
Lire w
Si x < y Alors
   Si x < z Alors
      Si x < w Alors
         plusPetit ← x
      Sinon
         plusPetit ← w
   Sinon
      Si z < w Alors
         plusPetit ← z
      Sinon
         plusPetit ← w
Sinon
   Si y < z Alors
      Si y < w Alors
         plusPetit ← y
      Sinon
         plusPetit ← w
   Sinon
      Si z < w Alors
         plusPetit ← z
      Sinon
         plusPetit ← w
Écrire plusPetit
// ...
static void Main(string []args)
{
   int x,
       y,
       z,
       w;
   int plusPetit;
   x = int.Parse(Console.ReadLine());
   y = int.Parse(Console.ReadLine());
   z = int.Parse(Console.ReadLine());
   w = int.Parse(Console.ReadLine());
   if (x < y)
   {
      if (x < z)
      {
         if (x < w)
         {
            plusPetit = x;
         }
         else
         {
            plusPetit = w;
         }
      }
      else
      {
         if (z < w)
         {
            plusPetit = z;
         }
         else
         {
            plusPetit = w;
         }
      }
   }
   else
   {
      if (y < z)
      {
         if (y < w)
         {
            plusPetit = y;
         }
         else
         {
            plusPetit = w;
         }
      }
      else
      {
         if (z < w)
         {
            plusPetit = z;
         }
         else
         {
            plusPetit = w;
         }
      }
   }
   Console.WriteLine(plusPetit);
}
// ...

... ce qui est lourd et se prête à erreur humaine. Ici, peu importe le chemin suivi, le programme nécessitera neuf opérations (quatre si on omet les entrées et les sorties), mais il devient plus délicat de s'assurer que le programme fait correctement son travail.

La forme imbriquée tend à prendre de l'expansion « à l'horizontale », et à compliquer l'écriture du code, mais est typiquement la plus efficace des deux formes, et est donc privilégiée avec un petit nombre de valeurs candidates.

Forme imbriquée équilibrée

Une alternative est dite imbriquée si elle contient au moins une alternative dans laquelle on trouve une autre alternative. Ceci est un constat général pour lequel il existe une grande variété de cas. Par exemple :

En pseudocodeEn code C#
RABAIS_BASE ← 2
RABAIS_ADDITIONNEL ← 3
PRIX_BASE ← 8
ÂGE_OR ← 65
ÂGE_OR_PLUS ← 75
prix ← PRIX_BASE
Lire âge
Si âge >= ÂGE_OR Alors
   prix ← prix - RABAIS_BASE
   Si âge >= ÂGE_OR_PLUS Alors
      prix ← prix - RABAIS_ADDITIONNEL
Écrire prix
// ...
static void Main(string []args)
{
   const int RABAIS_BASE = 2;
   const int RABAIS_ADDITIONNEL = 3;
   const int PRIX_BASE = 8;
   const int ÂGE_OR = 65;
   const int ÂGE_OR_PLUS = 75;
   int âge,
       prix;
   âge = int.Parse(Console.ReadLine());
   if (âge >= ÂGE_OR)
   {
      prix = prix - RABAIS_BASE;
      if (âge >= ÂGE_OR_PLUS)
      {
         prix = prix - RABAIS_ADDITIONNEL;
      }
   }
   Console.WriteLine(prix);
}
// ...

Une alternative imbriquée est équilibrée si le nombre d'opérations à faire entre la plus longue branche et la plus courte branche est d'au plus une étape. Le cas du programme trouvant le plus petit de trois nombres dans la forme proposée plus haut contient de telles alternatives.

Forme empilée

Résoudre ce problème avec une alternative de forme empilée signifie que nous visons à :

L'exemple qui suit illustre bien cette mécanique.

En pseudocodeEn code C#
Lire x
Lire y
Lire z
plusPetit ← x
Si y < plusPetit Alors
   plusPetit ← y
Si z < plusPetit Alors
   plusPetit ← z
Écrire plusPetit
// ...
static void Main(string []args)
{
   int x,
       y,
       z;
   int plusPetit;
   x = int.Parse(Console.ReadLine());
   y = int.Parse(Console.ReadLine());
   z = int.Parse(Console.ReadLine());
   plusPetit = x;
   if (y < plusPetit)
   {
      plusPetit = y;
   }
   if (z < plusPetit)
   {
      plusPetit = z;
   }
   Console.WriteLine(plusPetit);
}
// ...

Cette forme a la qualité importante de demeurer à toutes fins pratiques aussi simple peu importe le nombre de variables impliquées. Elle est par contre un peu moins équitable (et rapide) que la forme imbriquée : ici, on aura neuf opérations dans le pire cas (cinq si on omet les entrées/ sorties) et sept dans le meilleur cas (trois si on ne considère pas les entrées/ sorties).

Avec quatre variables, on a :

En pseudocodeEn code C#
Lire x
Lire y
Lire z
Lire w
plusPetit ← x
Si y < plusPetit Alors
   plusPetit ← y
Si z < plusPetit Alors
   plusPetit ← z
Si w < plusPetit Alors
   plusPetit ← w
Écrire plusPetit
// ...
static void Main(string []args)
{
   int x,
       y,
       z,
       w;
   int plusPetit;
   x = int.Parse(Console.ReadLine());
   y = int.Parse(Console.ReadLine());
   z = int.Parse(Console.ReadLine());
   w = int.Parse(Console.ReadLine());
   plusPetit = x;
   if (y < plusPetit)
   {
      plusPetit = y;
   }
   if (z < plusPetit)
   {
      plusPetit = z;
   }
   if (w < plusPetit)
   {
      plusPetit = w;
   }
   Console.WriteLine(plusPetit);
}
// ...

... ce qui est nettement plus simple que la forme imbriquée avec le même nombre de variables; la difficulté est essentiellement la même, peu importe le nombre de variables.


Valid XHTML 1.0 Transitional

CSS Valide !