TP3

NFA031

Exercice 1 : Etude de code (conditionnelles)

Problème: calcul du plus grand (max) parmi trois entiers (a,b,c) saisis au clavier.

Question 1: Cette partie examine plusieurs solutions à ce problème:

  1.   if (a>b) && (a>c)  max = a;
      if (b>a) && (b>c)  max = b;
      if (c>a) && (c>b)  max = c;
      Terminal.ecrireStringln("Le plus grand est "+ max);
    

  2.   if (a>b) 
         max = a;
      else 
         max = b;
      if (c > max)   
         max = c;
      Terminal.ecrireStringln("Le plus grand est "+ max);
    

  1. Commencez par établir un jeu de tests pour ce problème (sans vous soucier du code des solutions). Ce jeu de tests devrait vous permettre de tester n'importe quel programme qui lit trois entiers quelconques et qui donne la valeur du plus grand des trois.

  2. Qu'affichent ces programmes si (a) a=7, b=10, c=5; (b) a=7, b=7, c=5; (c) a=7, b=7, c=7. L'un de ces deux programmes n'as pas un comportément satisfaisant. Expliquez pourquoi et proposez une correction la plus simple possible.

  3. Comptez le nombre de test réalisez par chacun de ces deux programmes. Lequel est le plus économe en nombre de tests?

  4. On voudrait maintenant que le programme affiche non seulement la valeur la plus grande mais aussi le nom de la variable où elle se trouve. Modifiez (le plus simplement possible) ces deux programmes pour ce faire.

Question 2: Voici le squelette d'une solution au même problème, mais qu'il vous faut compléter. Dans cette version on veur également ajouter la condition qui est validée par chaque branche de la conditionnelle. Par exemple, dans la 1ère branche, on affichera a>= b et a>=c car cette condition est vraie à ce point de l'exécution.
 if (a>=b){
    if (a>=c){
       max = a; Terminal.ecrireStringln("a>=b et a>=c");
    }else{
       max = ?; Terminal.ecrireStringln("a>=b et c>a")
    }  
 }
 else if (b>=c){
       max = ?; Terminal.ecrireStringln(??)
 }
 else{ max = ?; Terminal.ecrireStringln(??)
 }
 Terminal.ecrireStringln("Le plus grand est "+ max);

Question 3: Modifiez le 2ème programme de la question 1 pour afficher les conditions validées par chaque branche (exactement comme pour la question précédente).

Exercice 2 : Plus de conditionnelles

On souhaite écrire un programme qui saisit 3 valeurs entières (x,y,z) et qui affiche ces valeurs dans l'ordre croissant (pas forcément strict). On veut mettre en oeuvre deux types d'algorithme:

  1. Dans la première solution, on détermine la place que doit occuper x: en premier, en deuxième, ou en dernier. Pour cela, on utilise une conditionnelle à trois branches, une par cas possible. Ensuite, dans chaque branche, on s'occupe de trouver l'ordre relatif de deux autres nombres. Cet algorithme peut être resumé ainsi:

    if (x < y && x < z) {         // x en premier
        afficher x, suivi de y et z dans le bon ordre
    }
    else if (x > y && x > z) {    // x en dernier
        afficher y et z dans le bon ordre, suivis par x
    }
    else {                        // x au milieu
        afficher x au milieur de y et z dans le bon ordre
    }
    

    Complétez cet algorithme et produisez un programme complet.

  2. Dans une deuxième solution, l'idée est de répondre à la question: ``dans quel ordre rélatif doit-on afficher x et y?''. Autrement dit: x avant y ou l'inverse? Cela nécessite une conditionnelle à deux branches. Ensuite, il suffit de déterminer, dans chaque branche, la place que doit occuper z. Détaillez cet algorithme et codez-le en java.

Exercice 3 : Premiers programmes (sans boucles)

Dans cet exercice vous devez utiliser le programme écrit lors du tp1 (exercice 4) afin de calculer le nombre de jours d'un mois pour une année donnée. Complétez ce programme afin de lire une date (jour, moi, année) et tester si celle ci correspond à une date correcte. Par exemple, le 20/03/2008 est une date correcte, alors que 30/02/2005 et 50/45/2000 ne le sont pas.

Afin de valider une date vous devrez vérifier si le nombre du jour est valide pour le mois donné. Par exemple, le 31/04 n'existe pas car il n'y a que 30 jours au mois de mars. De même, le 29/02/2001 n'existe pas, alors que le 29/02/2000 est une date valide. Vous devrez donc être en mesure d'appliquer l'algorithme de calcul du nombre de jours dans un mois pour une année donnée.

Exercice 4 : Etude de boucles

Les programmes suivants contiennent des boucles. Pour chacun de ces programmes, donnez un tableau qui retrace l'évolution des variables lors de chaque itération. Vous donnerez également la suite des messages affichés. Inspirez-vous des tableaux donnés au chapitre 3 pour suivre la trace d'un boucle.

Exemple: Voici un exemple extrait des notes de cours pour la boucle de calcul de la somme d'entier saisis au clavier:

public class Somme {
  public static void main (String[] args) {
     int n, total;
     // Initialisation de n,total
     Terminal.ecrireString("Un entier? ");
     Terminal.ecrireString("(fin avec 0): ");
     n = Terminal.lireInt();
     total = 0;
     while ( n !=0 )  {
        total = total + n;
        Terminal.ecrireString("Un entier? ");
        Terminal.ecrireString("(fin avec 0): ");
        n = Terminal.lireInt();
     }
     Terminal.ecrireString("La somme totale est: ");
     Terminal.ecrireIntln(total);
}}

Supposons une saisie de 5, 4, 7 et 0. Messages affichés par cette exécution:

% java Somme
Un entier? (fin avec 0) 5
Un entier? (fin avec 0) 4
Un entier? (fin avec 0) 7
Un entier? (fin avec 0) 0
La somme totale est: 16


Évolution des variables:

  init itération 1 itération 2 itération 3 itération 4
(n !=0)   (5 != 0) (4 != 0) (7 != 0) (0 != 0)
total 0 0+5 0+5+4 0+5+4+7 arrêt
n 5 4 7 0 arrêt

Les programmes à étudier:

  1. public class Puiss {
        public static void main (String[] args) {
            int a,b, p;
            Terminal.ecrireString("a? ");
            a = Terminal.lireInt();
            Terminal.ecrireString("b? ");
            b = Terminal.lireInt();
            p = 1;
            for (int i=b; i >= 1; i--)  {
                p = p * a;
           }       Terminal.ecrireStringln(a + " a la puissance " + b + " => " + p);
        }
    }
    

  2. class FactorielleSimple{
        public static void main(String[] argv){
           int n;
           Terminal.ecrireString("Entrez un nombre (petit): ");
           n = Terminal.lireInt();
           int res = 1;
           for (int i = 1; i<=n; i++){           res = res * i;
           }
           Terminal.ecrireString("La factorielle de "+n + " est ");
           Terminal.ecrireIntln(res);
        }
    }
    

Exercice 4: Étude de boucles (nombre d'itérations)

Considérez les boucles suivantes:

 //  Boucle 1
   int i = 5;
   while (i>0) { Terminal.ecrireStringln("Test");
                 i--;
   }

 //  Boucle 2
  int i = 0;
  while (i>0) { Terminal.ecrireStringln(``Test'');
                i--;
  }

 //  Boucle 3
  for (int i = 1; i != 5; i = i + 2) {
          Terminal.ecrireStringln("Test");
  }

 //  Boucle 4
  for (int i = 1; i>0;  i++) {
         Terminal.ecrireStringln("Test");
  }
 
 //  Boucle 5
  int i = 1;
  while (i < 100) {
          Terminal.ecrireStringln(i*i);
  }

  1. Combien de messages ``Test'' affichent les boucles 1, 2, 3 et 4?
  2. Écrivez une boucle for équivalente à la boucle 1 (c'est à dire qui s'exécute de façon identique).
  3. Combien de messages affiche la boucle 3 si on change int i = 1; en int i = 0;?
  4. Combien de tours réalise la boucle 5?

Exercice 5 : Boucle de validation d'une date

Modifiez le programme écrit dans l'exercice 3 afin de re-demander la date jusqu'à ce que celle-ci soit correcte. Le programme finit en affichant la date correcte saisie.



Francois Barthelemy
2012-10-15