Algorithmique & Programmation Orientée Objet Semestre 2 ST Structuration des programmes en sous-algorithmes
Cours | Exercices PDL | Exercices Java - Corrections
Clavier.class - Ecran.class - Documentation
Première partie Implantation en langage Java et validation des exercices de TD Exercice n°1: Sous-algorithmes "simples" a) Ecrire un sous-algorithme de calcul du sinus d'un angle donné en degrés.
Sinus.java /* Calcul du sinus d'un angle en degres */ static double sinus(double angle) { double sn; sn = Math.sin(angle*Math.PI/180.0); return sn; } Clavier.class - Ecran.class - Exemple d'exécution
b) Ecrire un sous-algorithme permettant de tester si un caractère est alphabétique (minuscule ou majuscule).
TestCaractereAlphabetique.java /* Test si un caractere est alphabetique ou non */ static boolean estAlphabetique(char c) { boolean res; if ( ( ( c >= 'a' ) && ( c <= 'z' ) ) || ( ( c >= 'A' ) && ( c <= 'Z' ) ) ) { res = true; } else { res = false; } return res; } Clavier.class - Ecran.class - Exemple d'exécution
c) Ecrire un sous-algorithme de lecture au clavier d'un nombre entier positif. Si l'utilisateur frappe une valeur non positive, il devra être sollicité de nouveau jusqu'à ce qu'il tape une valeur admissible.
LectureEntierPositif.java public class LectureEntierPositif { /* Lecture au clavier et retour d'un entier */ /* Saisie par essais successifs */ static int lectureEntierPositif() { int v; v = Clavier.saisirInt(); while ( v < 0 ) { Ecran.afficher("Erreur, resaisissez : "); v = Clavier.saisirInt(); } return v; } /* Programme principal */ public static void main(String [] args) { int n; Ecran.afficher("SVP, n : "); n = lectureEntierPositif(); Ecran.afficherln("Valeur lue = ",n); } } Clavier.class - Ecran.class - Exemple d'exécution
d) Ecrire un sous-algorithme de lecture au clavier d'un nombre réel compris dans un intervalle [min, max]. Si l'utilisateur frappe une valeur en dehors de l'intervalle, il devra être sollicité de nouveau jusqu'à ce qu'il tape une valeur admissible.
LectureReelDansIntervalle.java /* Lecture au clavier d'une valeur reelle */ /* comprise dans un intervalle et retour */ static double lectureReel(double min,double max) { double valeur; valeur = Clavier.saisirDouble(); while ( ( valeur < min ) || ( valeur > max ) ) { Ecran.afficher("Erreur, resaisissez : "); valeur = Clavier.saisirDouble(); } return valeur; } Clavier.class - Ecran.class - Exemple d'exécution
e) Ecrire un sous-algorithme d'affichage en hexadécimal d'un nombre entier. On considérera que le nombre à afficher est compris dans l'intervalle [0,255].
AffichageHexadecimal.java /* Affichage hexadecimal d'un chiffre */ static void affichageCaractereHexadecimal(int chiffre) { switch(chiffre) { case 10 : Ecran.afficher('A'); break; case 11 : Ecran.afficher('B'); break; case 12 : Ecran.afficher('C'); break; case 13 : Ecran.afficher('D'); break; case 14 : Ecran.afficher('E'); break; case 15 : Ecran.afficher('F'); break; default : Ecran.afficher(chiffre); break; } } /* Affichage hexadecimal d'un entier compris entre 0 et 255 */ static void affichageHexadecimal(int v) { int chiffreHaut; int chiffreBas; chiffreHaut = v/16; chiffreBas = v%16; affichageCaractereHexadecimal(chiffreHaut); affichageCaractereHexadecimal(chiffreBas); } Clavier.class - Ecran.class - Exemple d'exécution
f) Ecrire un sous-algorithme de calcul de la valeur de sin(a) au voisinage de 0.0 par développement limité. La formule de calcul est sin(a) = a - a3/3! + a5/5! - a7/7! + a9/9! - ...
DeveloppementLimiteSinus.java /* Calcul de la valeur de sin(a) au voisinage de 0.0 */ /* Utilisation du developpement limite */ /* Les valeurs a et n sont donnees */ static double sinus(double a,int n) { double sn; double terme; sn = a; terme = a; for ( int i = 3 ; i <= n ; i = i+2 ) { terme = -terme*a*a/i/(i-1); sn = sn + terme; } return sn; } Clavier.class - Ecran.class - Exemple d'exécution
Exercice n°2: Sous-algorithmes avec données agrégées a) Ecrire un sous-algorithme de calcul du sinus et du cosinus d'un angle donné en degrés. La seule solution est celle où on retourne une variable de type agrégé car le langage Java n'admet pas le passage de paramètre en résultat.
CosinusEtSinus.java /* Type agrege de stockage du cosinus */ /* et du sinus d'un angle */ static class CosEtSin { double cos = 1.0; double sin = 0.0; }; /* Calcul du cosinus et du sinus d'un angle */ /* donne en degres */ static CosEtSin calculCosinusEtSinus(double angle) { CosEtSin res = new CosEtSin(); double a; a = angle*Math.PI/180.0; res.cos = Math.cos(a); res.sin = Math.sin(a); return res; } Clavier.class - Ecran.class - Exemple d'exécution
b) Ecrire un sous-algorithme de test de l'inclusion d'un point de coordonnées (x,y) à l'intérieur d'un cercle de rayon r et de centre (cx,cy).
TestInclusion.java (solution sans type agrégé) /* Test de l'inclusion d'un point dans un cercle */ /* Les coordonnees du point sont donnees */ /* ainsi que le rayon et les coordonnees */ /* du centre du cercle */ static boolean testInclusion(double x, double y, double rayon, double cx, double cy) { boolean inclus; double distance; distance = Math.sqrt((x-cx)*(x-cx)+(y-cy)*(y-cy)); if ( distance < rayon ) { inclus = true; } else { inclus = false; } return inclus; } Clavier.class - Ecran.class - Exemple d'exécution
TestInclusionAvecStructure.java (solution avec types agrégés) /* Type agrege de stockage d'une position du plan */ static class Position2D { double x = 0.0; double y = 0.0; }; /* Type agrege de stockage d'un cercle du plan */ static class Cercle2D { Position2D centre = new Position2D(); double rayon = 1.0; }; /* Test de l'inclusion d'une position du plan */ /* dans un cercle du plan */ static boolean testInclusion(Position2D p, Cercle2D c) { double dx; double dy; double distance; boolean inclus; dx = p.x-c.centre.x; dy = p.y-c.centre.y; distance = Math.sqrt(dx*dx+dy*dy); inclus = ( distance <= c.rayon ); return inclus; } Clavier.class - Ecran.class - Exemple d'exécution
c) Ecrire un sous-algorithme de calcul de la surface d'un rectangle du plan à cotés parallèles aux axes.
SurfaceRectangle.java (solution sans type agrégé) /* Calcul de la surface d'un rectangle */ /* Les coordonnees de deux coins opposes */ /* sont donnees */ static double surfaceRectangle(double x1, double y1, double x2, double y2) { double surface; surface = Math.abs(x2-x1)*Math.abs(y2-y1); return surface; } Clavier.class - Ecran.class - Exemple d'exécution
SurfaceRectangleAvecStructure.java (solution avec types agrégés) /* Type agrege de stockage d'une position du plan */ static class Position2D { double x = 0.0; double y = 0.0; }; /* Type agrege de stockage d'un rectangle du plan */ static class Rectangle2D { Position2D p1 = new Position2D(); Position2D p2 = new Position2D(); }; /* Calcul de la surface d'un rectangle */ static double surfaceRectangle(Rectangle2D r) { double surface; surface = Math.abs(r.p2.x-r.p1.x)* Math.abs(r.p2.y-r.p1.y); return surface; } Clavier.class - Ecran.class - Exemple d'exécution
Exercice n°1fbis: Sous-algorithme à plusieurs niveaux Reprendre l'exercice 1f en programmant le calcul du développement limité avec utilisation de fonctions pour les calculs de puissance et de factoriel.
DeveloppementLimiteSinusAvecFonctions.java /* Calcul de la puissance entiere d'un reel */ /* Les valeurs a reelle et n entiere sont donnees */ static double puissance(double a,int n) { double res; int i; res = a; for ( i = 1 ; i < n ; i = i+1 ) res = res*a; return(res); } /* Calcul de n! */ /* La valeur n entiere est donnee */ static long factoriel(int n) { long fct; int i; fct = 1L; for ( i = 2 ; i <= n ; i = i+1 ) fct = fct*i; return(fct); } /* Calcul de la valeur de sin(a) au voisinage de 0.0 */ /* Utilisation du developpement limite */ /* Les valeurs a et n sont donnees */ static double sinus(double a,int n) { double signe; double sn; sn = a; signe = -1.0; for ( int i = 3 ; i <= n ; i = i+2 ) { sn = sn + signe*puissance(a,i)/factoriel(i); signe = -signe; } return sn; } Clavier.class - Ecran.class - Exemple d'exécution
Exercice n°3: Sous-algorithmes à plusieurs niveaux et données agrégées a) Ecrire un sous-algorithme de test si une année est bissextile.
TestBissextile.java /* Test si une annee est bissextile */ static boolean testBissextile(int annee) { boolean res; if ( annee%400 == 0 ) { res = true; } else { if ( annee%100 == 0 ) { res = false; } else { if ( annee%4 == 0 ) { res = true; } else { res = false; } } } return res; } Clavier.class - Ecran.class - Exemple d'exécution
b) Ecrire un sous-algorithme de calcul du nombre de jours d'un mois codé sous la forme d'un nombre.
NombreJoursMois.java /* Calcul du nombre de jours d'un mois */ static int nombreJoursMois(int mois,int annee) { int res; switch (mois) { case 1 : case 3 : case 5 : case 7 : case 8 : case 10 : case 12 : { res = 31; } break; case 4 : case 6 : case 9 : case 11 : { res = 30; } break; case 2 : { if ( testBissextile(annee) == true ) { res = 29; } else { res = 28; } } break; default : { res = -1; } break; } return res; } Clavier.class - Ecran.class - Exemple d'exécution
c) Ecrire un sous-algorithme de calcul de la date du jour suivant immédiatement une date codée sous la forme jour-mois-année en nombres.
JourSuivant.java /* Type agrege de stockage d'une date */ /* formee d'un numero de jour, d'un numero */ /* de mois et d'un numero d'annee */ static class Date { int jour = 1; int mois = 1; int annee = 1901; }; /* Calcul du jour suivant une date codee */ /* sous la forme jour mois annee en entier */ static Date jourSuivant(Date d) { Date res = new Date(); res.jour = d.jour+1; res.mois = d.mois; res.annee = d.annee; if ( res.jour > nombreJoursMois(d.mois,d.annee) ) { res.jour = 1; res.mois = res.mois+1; if ( res.mois > 12 ) { res.mois = 1; res.annee = res.annee+1; } } return res; } Clavier.class - Ecran.class - Exemple d'exécution
d) Ecrire un sous-algorithme de modification d'une date codée sous la forme jour-mois-année en nombres pour l'incrémenter de un jour.
JourDApres.java /* Type agrege de stockage d'une date */ /* formee d'un numero de jour, d'un numero */ /* de mois et d'un numero d'annee */ static class Date { int jour = 1; int mois = 1; int annee = 1901; }; /* Calcul du jour suivant un jour code */ /* sous la forme jour mois annee en entier */ static void jourSuivant(Date d,Date res) { res.jour = d.jour+1; res.mois = d.mois; res.annee = d.annee; if ( res.jour > nombreJoursMois(d.mois,d.annee) ) { res.jour = 1; res.mois = res.mois+1; if ( res.mois > 12 ) { res.mois = 1; res.annee = res.annee+1; } } } /* Modification d'un jour code sous forme */ /* jour mois annee en entier */ /* pour l'incrementer d'un jour */ static void jourDApres(Date d) { d.jour = d.jour+1; if ( d.jour > nombreJoursMois(d.mois,d.annee) ) { d.jour = 1; d.mois = d.mois+1; if ( d.mois > 12 ) { d.mois = 1; d.annee = d.annee+1; } } } /* Modification d'un jour code sous forme */ /* jour mois annee en entier */ /* pour l'incrementer d'un jour */ static void jourDApres2(Date d) { jourSuivant(d,d); } Clavier.class - Ecran.class - Exemple d'exécution
Seconde partie: Exercices supplémentaires Exercice n°4 Ecrire un sous-algorithme de calcul d'une valeur aléatoire entière comprise entre 0 et n compris (n entier strictement positif).
NombreAleatoireEntier.java /* Lecture au clavier et retour d'un entier */ /* Saisie par essais successifs */ static int nombreAleatoire(int n) { double v; v = (n+1)*Math.random(); return (int) (v); } Clavier.class - Ecran.class - Exemple d'exécution
Exercice n°5 On considère le type agrégé Date suivant: static class Date { int jour = 1; int mois = 1; int annee = 1901; }; a) Ecrire un sous-algorithme de saisie au clavier d'une Date. Ecrire un sous-algorithme d'affichage écran d'une date formatée sous la forme "jj/mm/aaaa".
DateLecture.java /* Lecture au clavier et retour d'une date */ static Date saisirDate() { Date d = new Date(); Ecran.afficher("Jour ? "); d.jour = Clavier.saisirInt(); Ecran.afficher("Mois ? "); d.mois = Clavier.saisirInt(); Ecran.afficher("Annee ? "); d.annee = Clavier.saisirInt(); return d; } Clavier.class - Ecran.class - Exemple d'exécution
DateAffichage.java /* Affichage d'une date au format jj/mm/aaaa */ static void afficher(Date d) { if ( d.jour < 10 ) { Ecran.afficher("0"); } Ecran.afficher(d.jour); Ecran.afficher("/"); if ( d.mois < 10 ) { Ecran.afficher("0"); } Ecran.afficher(d.mois); Ecran.afficher("/"); if ( d.annee < 10 ) { Ecran.afficher("0"); } if ( d.annee < 100 ) { Ecran.afficher("0"); } if ( d.annee < 1000 ) { Ecran.afficher("0"); } Ecran.afficher(d.annee); } Clavier.class - Ecran.class - Exemple d'exécution
b) Ecrire un sous-algorithme d'affectation d'une Date avec une autre Date.
DateAffectation.java /* Affectation de la Date cible */ /* avec les valeurs stockees dans les champs */ /* de la date source */ static void affectation(Date cible,Date source) { cible.annee = source.annee; cible.mois = source.mois; cible.jour = source.jour; } Clavier.class - Ecran.class - Exemple d'exécution
c) Ecrire un sous-algorithme de test de l'égalité de deux Date.
DateTestEgalite.java /* Test de l'egalite de deux Date */ static boolean testEgalite(Date d1,Date d2) { boolean res; if ( ( d1.jour == d2.jour ) && ( d1.mois == d2.mois ) && ( d1.annee == d2.annee ) ) { res = true; } else { res = false; } return res; } Clavier.class - Ecran.class - Exemple d'exécution
d) Ecrire un sous-algorithme de test d'antériorité d'une Date par rapport à une autre Date.
DateTestAnteriorite.java /* Test de l'egalite de deux Date */ static boolean testAnteriorite(Date d1,Date d2) { boolean res; if ( d1.annee < d2.annee ) { res = true; } else { if ( d1.annee > d2.annee ) { res = false; } else { if ( d1.mois < d2.mois ) { res = true; } else { if ( d1.mois > d2.mois ) { res = false; } else { if ( d1.jour < d2.jour ) { res = true; } else { res = false; } } } } } return res; } Clavier.class - Ecran.class - Exemple d'exécution
Auteur: Nicolas JANEY UFR Sciences et Techniques Université de Besançon 16 Route de Gray, 25030 Besançon nicolas.janey@univ-fcomte.fr