Exercices Java : Les boucles - somme des carrés - sondage - traingle
Rédigé par GC Team, Publié le 18 Mars 2010, Mise à jour le Jeudi, 17 Avril 2025 00:30
Exercices Java : deroulement et etude d exécution d'un programme - boucle for et while
Dans cet exemple, nous allons suivre pas à pas l’exécution d’un programme. Les instructions d’un programme peuvent changer la mémoire, c’est à dire les valeurs des variables, et avoir des effets, notamment via les entrées-sorties écran-clavier. Les déclarations pour leur part, ont pour conséquence de créer de nouvelles variables. Nous allons retracer dans un tableau synthétique l’évolution pas à pas d’un programme, en notant l’effet produit par les déclarations et instructions. Ce tableau va comporter une première colonne référant aux numéros de ligne du programme. Une colonne servira à noter la valeur des conditions des instructions conditionnelles et des boucles. Ensuite, il y aura une colonne pour chaque variables et pour finir une colonne pour les entrées clavier et une colonne pour les sorites à l’écran. Nous noterons qu’une variable n’est pas définie en inscrivant le sigle NEP (pour N’Existe Pas) dans la colonne correspondante. Un point d’interrogation est utilisé quand la variable existe (elle a été déclarée),mais elle n’a pas été initialisée.
1 |
class Exemple5_0 { |
Et voici le tableau qui retrace l’exécution de ce programme :
nb | test | total | x | i | clavier | écran |
4 5 6 7 8 8.init 8.test 9 8.modif 8.test 9 8.modif 8.test 9 8.modif 8.test 9 8.modif 8.test 10 11 12 13 |
true
true
true
true
false
|
NEP 0 0 0 0 0 0 3 3 3 9 9 9 18 18 18 30 30 30 30 30 30 30 |
NEP NEP ? ? NEP 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 |
NEP NEP NEP NEP NEP 1 1 1 2 2 2 3 3 3 4 4 4 5 5 NEP NEP NEP NEP |
3 |
Entrez le multiplicateur :
La somme des 4 premiers multiples est : |
La première ligne du tableau montre l’état initial avant exécution. {sidebar id=8}
L’instruction for a trois morceaux intervenant à des moments différents, c’est pourquoi on adistingué es effets de l’initialisation, du test de la condition i<=4 (quand la condition vaut true, la boucle se poursuit, quand elle vaut false, la boucle s’arrête), et de la modification de la variable i. Les autres types de boucle (while et do ... while) ne comportent qu’un partie test.
La ligne 10 est prise en compte en ceci que l’accolade ferme un bloc, ce qui met fin à l’existence de la variable i qui est locale à ce bloc. On aurait pu de même prendre en compte la ligne 14 qui met fin aux variables total et x.
Un tel tableau relate une exécution donnée. Si on change la valeur x entrée ligne 7, il faut changer tout le tableau.
On voit sur cet exemple que le corps de la boucle, la ligne 9, est exécutée 4 fois au cours du programme.
Exercice : déroulement d’une boucle for
Avec un tableau comme celui donné dans l’exemple 5.0, retracez une exécution du programme suivant dans laquelle on entre au clavier la valeur 5
1 |
class Exo5_1{ |
Exercice : déroulement d’une boucle while
1 |
class Exo6_2{ |
1. Que calcule ce programme ?
2. Avec un tableau comme celui donné dans l’exemple 5.0, retracez une exécution du programme suivant dans laquelle on entre au clavier la valeur 8.
Exercice 3 : étude de boucles (nombre d’itérations)
Considérez les boucles suivantes :{sidebar id=1}
1 |
/ / Boucle 1 |
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 ?
5. Quels sont les messages affichés par :
1 |
public class Boucle6 { |
Exercice JAVA masquage (shadowing) et héritage
Indiquer l'affichage du programme. Attention aux situations de masquage.
Masquage (Shadowing), Héritage
Alphabet.java
Vous trouverez ci-dessous le programme Alphabet qui implémente la hiérarchie de 3 classes (A, B et C). Indiquez l'affichage du programme (sans l'exécuter). Attention aux situations de shadowing.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
class Alphabet { public static void main(String args[]) { A[] as = new A[3]; as[0] = new A(1); as[1] = new B(2); as[2] = new C(3); for (int i = 0; i < as.length; i++) { as[i].afficherClasse(); System.out.println("-----"); } for (int i = 0; i < as.length; i++) { as[i].afficherVariables(); System.out.println("-----"); } } } class A { protected int a = 5; public A(int a) { this.a = a; } public void afficherClasse() { System.out.println("Classe A"); } public void afficherVariables() { System.out.println("a = " + a); } } class B extends A { protected int b = 6; public B(int b) { super(2 * b); a = b; } public void afficherClasse() { super.afficherClasse(); System.out.println("Classe B"); } public void afficherVariables() { super.afficherVariables(); System.out.println("b = " + b); } } class C extends B { protected int b = 7; protected int c = 8; public C(int c) { super(3 * c); b = c; } public void afficherClasse() { super.afficherClasse(); System.out.println("Classe C"); } public void afficherVariables() { super.afficherVariables(); System.out.println("c = " + c); } } |
L'affichage correct et donné ci-dessous.
Classe A ----- Classe A Classe B ----- Classe A Classe B Classe C ----- a = 1 ----- a = 2 b = 6 ----- a = 9 b = 6 c = 8
La difficulté principale réside dans l'affichage du dernier objet (de type C).
Pourquoi l'attribut b vaut-il 6 et non pas 3 ?
Réponse : à cause du masquage. En effet, si on observe la hiérarchie de classes donnée, on peut remarquer qu'un objet de type C possède en fait deux attributs b : l'un hérité de B et l'autre redéfini dans C (qui masque le premier).
Lorsque la méthode afficherVariables va être invoquée sur l'objet de type C, elle va appeler la méthode afficherVariables de la super-classe (B). Cette dernière va afficher l'attribut b de la super-classe, qui vaut 6.
Pour bien comprendre la nuance, remplacez la méthode afficherVariables de la classe C par la suivante :
public void afficherVariables() { super.afficherVariables(); System.out.println("b (masquant) = " + b); System.out.println("c = " + c); } |
Ré-exécutez le programme. L'affichage devrait alors être le suivant:
Classe A ----- Classe A Classe B ----- Classe A Classe B Classe C ----- a = 1 ----- a = 2 b = 6 ----- a = 9 b = 6 b (masquant) = 3 c = 8 -----
Exercice polymorphisme et récursivité expressions arithmétiques
But:
|
Révisions: Comparaison d'une approche procédurale avec une approche orientée objet | |||
Thème:
|
Polymorphisme, Récursivité | |||
Fichiers:
|
Arith.java |
Johnny C. est étudiant en première année à l'EPFL. Il doit écrire un programme Java simple permettant d'évaluer des expressions arithmétiques. Ces expressions sont constituées de nombres, d'additions et de multiplications; comme ceci :
2 + 5 * 3
Johnny n'a pas encore très bien absorbé les concepts orientés objets permis par Java et il produit la solution suivante :
Arith.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
/** Structure de donnee pour les expressions*/ class Expression { public int type; public int value; public Expression leftOp; public Expression rightOp; public Expression(int type, int value, Expression leftOp, Expression rightOp) { this.type = type; this.value = value; this.leftOp = leftOp; this.rightOp = rightOp; } } /** Classe principale */ class Arith { /** Constantes pour representer les types*/ public static final int TYPE_NUMBER = 1; public static final int TYPE_SUM = 2; public static final int TYPE_PROD = 3; public static void main(String [] args) { // construit l'expression 3 + 2 * 5 Expression term = new Expression(TYPE_SUM, 0, new Expression(TYPE_NUMBER, 3, null, null), new Expression(TYPE_PROD, 0, new Expression(TYPE_NUMBER, 2, null, null), new Expression(TYPE_NUMBER, 5, null, null))); System.out.println(evaluate(term)); } /** Evalue recursivement l'expression */ public static int evaluate(Expression term) { switch (term.type) { case TYPE_NUMBER: return term.value; case TYPE_SUM: return evaluate(term.leftOp) + evaluate(term.rightOp); case TYPE_PROD: return evaluate(term.leftOp) * evaluate(term.rightOp); default: return 0; //erreur, ne devrait jamais se produire } } } |
Le programme de Johnny fonctionne, mais est écrit dans un style "procédural" plutôt qu'orienté objet. Il peut donc, à cet égard, être amélioré.
- Réflechissez à la solution de Johnny et essayez d'expliquer pourquoi elle n'est pas très bonne et comment elle pourrait être améliorée.
- Ecrivez une version améliorée (commencez par lire l'intégralité des recommandations avant de commencer à programmer) :
- Définissez une classe abstraite Expression qui déclarera une méthode abstraite evaluate.
- Créez des classes distinctes pour chaque type d'expressions (Number, Sum, Product) et faites les hériter de Expression.
- Vous pouvez éviter de la duplication inutile de code en créeant une classe abstraite intermédiaire BinOp qui contiendra les attributs leftOp et rightOp représentants respectivement les opérandes gauche et droit d'un expression binaire. Faites hériter Sum et Product de Binop.
- Adaptez la méthode main de la classe principale à votre nouvelle structure.
- Pour comparer la solution originale de Johnny à la votre, faites évoluer votre programme dans le sens suivant :
- Ajouter la possibilité de générer la représentation de votre expression sous la forme d'une chaîne de caractère. Par exemple si votre expression est le nombre 13, cette fonctionalité doit vous retourner la chaîne "13". Si c'est une Sum avec 12 et 13 comme leftOp et rightOp respectivement, la fonctionalité en question devra retourner la chaîne "12 * 13".
- Ajouter un nouveau type d'expression binaire : Modulo représentant des expressions binaires dont l'évaluation retourne le reste de la division entière de leftOp par rightOp.
Portez un regard critique à votre nouvelle version. Si vous avez dû faire du "copier-coller" de portions de votre code pour ajouter ces facilités, c'est qu'il y a encore des problèmes de conception. Essayer de faire en sorte qu'il n'y ait aucune duplication inutile de code.
Une fois satisfait de votre version, essayez d'ajouter les mêmes facilités au programme de Johnny.
Laquelle des deux versions a été la plus facile à modifier ?
Note : cet exercice a essentiellement pour but d'illustrer l'intérêt du polymorphisme. Afin de nous concentrer sur cet aspect nous nous autoriserons quelques "entorses" au principe d'une bonne encapsulation (privacité des attributs). Une fois que vous aurez réussi à produire une solution polymorphique et à en dégager l'intérêt par rapport au code d'origine, le soin vous est laissé de parfaire votre code en vous concentrant cette fois sur son encapsulation.
Le programme de Johnny fonctionne, mais est écrit dans un style "procédural" plutôt qu'orienté objet. Il peut donc, à cet égard, être amélioré.
- Réflechissez à la solution de Johnny et essayez d'expliquer pourquoi elle n'est pas très bonne et comment elle pourrait être améliorée.
- Ecrivez une version améliorée (commencez par lire l'intégralité des recommandations avant de commencer à programmer) :
- Définissez une classe abstraite Expression qui déclarera une méthode abstraite evaluate.
- Créez des classes distinctes pour chaque type d'expressions (Number, Sum, Product) et faites les hériter de Expression.
- Vous pouvez éviter de la duplication inutile de code en créeant une classe abstraite intermédiaire BinOp qui contiendra les attributs leftOp et rightOp représentants respectivement les opérandes gauche et droit d'un expression binaire. Faites hériter Sum et Product de Binop.
- Adaptez la méthode main de la classe principale à votre nouvelle structure.
- Pour comparer la solution originale de Johnny à la votre, faites évoluer votre programme dans le sens suivant :
- Ajouter la possibilité de générer la représentation de votre expression sous la forme d'une chaîne de caractère. Par exemple si votre expression est le nombre 13, cette fonctionalité doit vous retourner la chaîne "13". Si c'est une Sum avec 12 et 13 comme leftOp et rightOp respectivement, la fonctionalité en question devra retourner la chaîne "12 * 13".
- Ajouter un nouveau type d'expression binaire : Modulo représentant des expressions binaires dont l'évaluation retourne le reste de la division entière de leftOp par rightOp.
Portez un regard critique à votre nouvelle version. Si vous avez dû faire du "copier-coller" de portions de votre code pour ajouter ces facilités, c'est qu'il y a encore des problèmes de conception. Essayer de faire en sorte qu'il n'y ait aucune duplication inutile de code.
Une fois satisfait de votre version, essayez d'ajouter les mêmes facilités au programme de Johnny.
Laquelle des deux versions a été la plus facile à modifier ?
Note : cet exercice a essentiellement pour but d'illustrer l'intérêt du polymorphisme. Afin de nous concentrer sur cet aspect nous nous autoriserons quelques "entorses" au principe d'une bonne encapsulation (privacité des attributs). Une fois que vous aurez réussi à produire une solution polymorphique et à en dégager l'intérêt par rapport au code d'origine, le soin vous est laissé de parfaire votre code en vous concentrant cette fois sur son encapsulation.
Exercice JAVA modularisation - erreurs fréquentes dans les méthodes
But:
|
Trouver des erreurs dans le codage de méthodes | |||
Thème:
|
Modularisation | |||
Fichiers:
|
ErreursMethodes.java |
Chacune des méthodes methode1 à methode8 dans le programme ErreursMethodes.java ci-dessous contient une seule erreur syntaxique. Il s'agit d'erreurs liées à l'utilisation des paramètres, des variables ou de la valeur retournée par la méthode. Il n'y pas d'erreurs dans la méthode main, ni dans la méthode methodeSansErreurs. Trouvez et corrigez les erreurs !
Si vous sollicitez l'aide du compilateur pour trouver les erreurs, sachez qu'il aura de la peine avec ce type de programme où il y a beaucoup d'erreurs de structure. Il peut vous montrer la ligne approximative où se trouve une erreur, mais la solution proposée n'est pas toujours correcte, la liste des erreurs n'est pas toujours complète et les erreurs ne sont pas présentées dans le bon ordre. Dans ce genre de situation, utilisez surtout votre bon sens et vos propres connaissances de la syntaxe de Java.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
class ErreursMethodes { public static void main (String[] args) { int i1 = methode1(); int i2 = methode2(); int i3 = methode3(); int i4 = methode4(); methode5(); methode6(); methode7(); methode8(); } static int methode1 { int a = 0; System.out.println("Méthode 1"); return a; } static int methode2 () { int a = 0; i1 = 10; System.out.println("Méthode 2"); return a; } static int methode3 () { int a = 0; System.out.println("Méthode 3"); } static int methode4 () { String a = "0"; System.out.println("Méthode 4"); return a; } static void methode5 () { double a = 0; System.out.println("Méthode 5"); return a; } static methode6 () { double a = 0; System.out.println("Méthode 6"); return a; } static void methode7 () { int a = 0; double b = 5.5; methodeSansErreur(a); System.out.println("Méthode 7"); } static void methode8 () { int a = 0; String b = "5.5"; methodeSansErreur(a, b); System.out.println("Méthode 8"); } static void methodeSansErreur (int a, double b) { // Cette méthode ne fait rien du tout } } |
Fichiers:
|
ErreursMethodesCorrige.java |
- methode1: Même s'il n'y a pas d'arguments à envoyer à la méthode, il doit y avoir une liste de paramètres dans l'en-tête. Dans ce cas, il faut ajouter des parenthèses vides.
- methode2: Il y a une référence à la variable i1 qui n'est pas visible dans la méthode methode2. La portée d'une variable est limitée à son bloc de déclaration, dans le cas de i1 à la méthode main.
- methode3: La dernière instruction exécutée n'est pas return. Cette instruction est obligatoire pour toutes les méthodes qui retourne une valeur, i.e. qui n'a pas le type void dans l'en-tête.
- methode4: Le type de la valeur retournée n'est pas le même que le type specifié dans l'en-tête de la méthode.
- methode5: La méthode essaie de retourner une valeur avec return. Cela n'est pas possible si l'en-tête de la méthode est void.
- methode6: La méthode n'a pas de type pour la valeur retournée. Si la méthode ne retourne pas de valeur, il faut indiquer void dans l'en-tête.
- methode7: La méthode sansErreur est appelée avec 1 argument tandis qu'elle en demande 2. Le nombre d'arguments doit toujours correspondre au nombre de paramètres.
- methode8: La méthode sansErreur est maintenant appelée avec 2 arguments, ce qui est correct, mais le type des arguments ne correspond pas au type des paramètres.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
class ErreursMethodesCorrige { public static void main (String[] args) { int i1 = methode1(); int i2 = methode2(); int i3 = methode3(); int i4 = methode4(); methode5(); methode6(); methode7(); methode8(); } static int methode1 () { int a = 0; System.out.println("Méthode 1"); return a; } static int methode2 () { int a = 0; // i1 = 10; System.out.println("Méthode 2"); return a; } static int methode3 () { int a = 0; System.out.println("Méthode 3"); return a; } static int methode4 () { // String a = "0"; int a = 0; System.out.println("Méthode 4"); return a; } static void methode5 () { double a = 0; System.out.println("Méthode 5"); // return a; } static double methode6 () { double a = 0; System.out.println("Méthode 6"); return a; } static void methode7 () { int a = 0; double b = 5.5; methodeSansErreur(a, b); System.out.println("Méthode 7"); } static void methode8 () { int a = 0; // String b = "5.5"; double b = 5.5; methodeSansErreur(a, b); System.out.println("Méthode 8"); } static void methodeSansErreur (int a, double b) { // Cette méthode ne fait rien du tout } } |
Exercice POO de base - trouver les erreurs
But:
|
Trouver l'erreur dans un programme donné | |||
Thème:
|
POO de base | |||
Fichiers:
|
Erreurs.java |
Le fichier Erreurs.java contient les déclarations de deux classes. La classe Erreurs contient une méthode main et sert à démarrer le programme. La classe GrillePain sert à représenter des grille-pains dans le programme sous forme d'objets dotés de deux variables d'instance: l'année de fabrication et le nombre de tranches que l'appareil peut griller. Il y a également une méthode d'instance afficherVariables que l'on peut appliquer sur un objet de type GrillePain afin d'afficher les valeurs de ses variables d'instance.
- Eclipse vous signale des messages d'erreurs à propos de ce programme. Pourquoi? Corrigez-les.
- L'affichage lors de l'exécution montre que la variable d'instance nbTranches a la valeur 0 pour les deux grille-pains même si l'on a envoyé une autre valeur à la méthode constructeur. Pourquoi? Corrigez le programme.
Exemple d'exécution du programme (après la première correction):
Objet de type GrillePain avec variables d'instance annee = 1995 et nbTranches = 2 Objet de type GrillePain avec variables d'instance annee = 1998 et nbTranches = 4
Code donné:
Erreurs.java
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class Erreurs { public static void main(String[] args) { GrillePain g1 = new GrillePain(1995, 2); g1.afficherVariables(); GrillePain g2 = new GrillePain(1998, 4); g2.afficherVariables(); } } class GrillePain { private int annee; private int nbTranches; private GrillePain(int a, int nbTranches) { annee = a; nbTranches = nbTranches; } private void afficherVariables() { System.out.println ("Objet de type GrillePain avec variables d'instance année = " + annee + " et nbTranches = " + nbTranches); } } |
Fichiers:
|
Erreurs.java |
- Le programmeur a trop utilisé le mot-clé private au point que l'on ne peut même pas accéder à la méthode constructeur depuis l'extérieur de la classe, ni à la méthode afficherVariables(). Il faut rendre ces deux méthodes publiques en supprimant le mot-clé private.
- Les variables d'instance (mais pas les variables locales) reçoivent toujours des valeurs par défaut. Si la variable d'instance nbTranches n'est pas initialisée, elle aura donc la valeur 0. Dans la méthode constructeur, il y a une situation de shadowing où le paramètre a le même nom que la variable d'instance. Il faut utiliser l'objet this pour différencier les deux et ainsi affecter la valeur du paramètre nbTranches à la variable d'instance nbTranches.
Erreurs.java
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/* Version corrigée */ class Erreurs { public static void main (String[] args) { GrillePain g1 = new GrillePain(1995, 2); g1.afficherVariables(); GrillePain g2 = new GrillePain(1998, 4); g2.afficherVariables(); } } class GrillePain { private int annee; private int nbTranches; public GrillePain (int a, int nbTranches) { // !!! pas de private annee = a; this.nbTranches = nbTranches; // !!! this } public void afficherVariables() { // !!! pas de private System.out.println ("Objet de type GrillePain avec variables d'instance année = " + annee + " et nbTranches = " + nbTranches); } } |
Exercice placement sans recouvrement - tableaux et modularisation
Placer sans recouvrement des objets linéaires sur une grille carrée
tableaux, Modularisation, algorithme
Le but de cet exercice est de placer sans recouvrement (i.e. on ne peut plus utiliser une case déjà utilisée) des objets linéaires sur une grille carrée. Cela pourrait être par exemple une partie d'un programme de bataille navale. Vous considérerez que la grille est de taille 10 x 10.
Dans le fichier Recouvrement.java :
-
Ecrivez une méthode auxiliaire :
static boolean remplitGrille(boolean [][] grille, int ligne, int colonne, char direction, int longueur);
dont le rôle est de vérifier si le placement dans une grille (voir ci-dessous) d'un objet de dimension longueur est possible, en partant de la coordonnée (ligne,colonne) et dans la direction définie par direction (Nord, Sud, Est ou Ouest).
Si le placement est possible, la méthode devra de plus effectuer ce placement (voir ci-dessous la description de la grille).La méthode devra indiquer (par la valeur de retour) si le placement a pu être réalisé ou non.
- Dans la méthode main
- Définissez une variable nommée grille, correspondant à un tableau de booléens, de taille fixe, à deux dimensions, avec dim comme paramètre de taille pour chaque dimension (on a donc une grille carrée).
La valeur true dans une case [i][j] de cette grille représente le fait qu'un (bout d')objet occupe la case de coordonnées (i, i). - Utilisez la méthode précédente pour remplir interactivement la grille, en demandant à l'utilisateur de spécifier la position, la taille et la direction des objets à placer.
Indiquez à chaque fois à l'utilisateur si l'élément a pu ou non être placé dans la grille.
Le remplissage se termine lorsque l'utilisateur entre une longueur strictement inférieure à 0. - Terminer alors en "dessinant" la grille : afficher un '.' si la case est vide et un '#' si la case est occupée.
- Définissez une variable nommée grille, correspondant à un tableau de booléens, de taille fixe, à deux dimensions, avec dim comme paramètre de taille pour chaque dimension (on a donc une grille carrée).
Remarques :
- Dans l'interface utilisateur, pour indiquer les positions, utilisez au choix soit les coordonnées de Java : 0 à taille de la grille -1 (plus facile), soit les coordonnées usuelles (1 à taille de la grille, un peu plus difficile) ,
- Pensez à effectuer des tests de validité sur les valeurs entrées (débordement du tableau).
- pour représenter la direction, vous pouvez utiliser un caractère ('N' pour nord. 'S' pour sud, etc...)
- N'oubliez pas d'initialiser la grille en tout début de programme !
Exemple de fonctionnement :
Entrez la taille (négative pour arrêter le programme): 3 Entrez coord. x : 0 Entrez coord. y : 0 Entrez direction (N,S,E,O) : S Placement en (0,0) direction S longueur 3 -> Succès #......... #......... #......... .......... .......... .......... .......... .......... .......... .......... Entrez la taille (négative pour arrêter le programme): 5 Entrez coord. x : 2 Entrez coord. y : 4 Entrez direction (N,S,E,O) : N Placement en (2,4) direction N longueur 5 -> Echec Entrez la taille (négative pour arrêter le programme): 5 Entrez coord. x : 2 Entrez coord. y : 4 Entrez direction (N,S,E,O) : E Placement en (2,4) direction E longueur 5 -> Succès #......... #......... #...#####. .......... .......... .......... .......... .......... .......... .......... Entrez la taille (négative pour arrêter le programme): -1 Merci d'avoir joué!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
import java.util.Scanner; class Recouvrement { private static Scanner scanner = new Scanner(System.in); public static void main(String[] args) { boolean [][] grille = new boolean [10][10]; initGrille(grille); ajouterElements(grille); System.out.println("\nMerci d'avoir joué!"); } /** * Essaie de remplir la grille avec un objet de longueur donnée * dans une direction donnée en partant des coordonnées * (targetRow, targetCol). * @param grille * @param targetRow * @param targetCol * @param direction * @param longueur * @return true si le placement est réussi et false sinon */ static boolean remplitGrille(boolean [][] grille, int targetRow, int targetCol, char direction, int longueur) { int deltaRow = 0, deltaCol = 0; int dim = grille.length; // On calcule ici la direction dans laquelle aller depuis // les coordonnées indiquées par l'utilisateur. // Ex: pour aller au nord, il faut monter d'une // ligne en restant sur la // même colonne. switch (direction) { case 'N': deltaRow = -1; deltaCol = 0; break; case 'S': deltaRow = 1; deltaCol = 0; break; case 'E': deltaRow = 0; deltaCol = 1; break; case 'O': deltaRow = 0; deltaCol = -1; break; } // On se place sur la case de départ int tempRow = targetRow; int tempCol = targetCol; // Est-il possible de placer l'élément ? boolean possible = true; // Avant de modifier la grille il faut vérifier s'il est // possible de mettre tout l'objet for (int i = 0; (i < longueur && possible); i++) { if ((tempRow < 0) || (tempRow >= dim)) { possible = false; } else if ((tempCol < 0) || (tempCol >= dim)) { possible = false; } else if (grille [tempRow][tempCol]) { possible = false; } // On se déplace sur la case suivante tempRow += deltaRow; tempCol += deltaCol; } // Le placement est possible, et on peut donc mettre // à jour la grille if (possible) { tempRow = targetRow; tempCol = targetCol; for (int i = 0; i < longueur; i++) { grille [tempRow][tempCol] = true; tempRow += deltaRow; tempCol += deltaCol; } } return possible; } /** * Initialise toutes les cases de la grille à false * @param grille */ static void initGrille(boolean[][] grille) { int dim = grille.length; for (int row = 0; row < dim; row++) { for (int col = 0; col < dim; col++) { grille[row][col] = false; } } } /** * Permet à l'utilisateur de demander le placement d'objets * sur la grille. * @param grille */ static void ajouterElements(boolean[][] grille) { int col, row; char dir; int length; System.out.print("Entrez la taille " + "(négative pour arrêter le programme): "); length = scanner.nextInt(); // L'utilisateur signifie qu'il veut arrêter // d'introduire des objets en spécifiant une //longueur négative while (length >= 0) { do { System.out.print("Entrez coord. x : "); col = scanner.nextInt(); } while ((col < 0) || (col >= grille.length)); do { System.out.print("Entrez coord. y : "); row = scanner.nextInt(); } while ((row < 0) ||(row >= grille.length)); do { System.out.print("Entrez direction (N,S,E,O) : "); dir = scanner.next().charAt(0); } while ((dir != 'N') && (dir != 'S') && (dir != 'E') && (dir != 'O')); System.out.print("Placement en (" + col + "," + row + ") direction " + dir + " longueur " + length + " -> "); if (remplitGrille(grille, col, row, dir, length)) { System.out.println("Succès"); afficheGrille(grille); } else { System.out.println("Echec"); } System.out.println(); System.out.print("Entrez la taille " + "(négative pour arrêter le programme): "); length = scanner.nextInt(); } } /** * Affichage de la grille * @param grille */ static void afficheGrille(boolean[][] grille) { int dim = grille.length; for (int row = 0; row < dim; row++) { for (int col = 0; col < dim; col++) { if (grille[row][col]) System.out.print("#"); else System.out.print("."); } System.out.println(); } } } |
Exercice java transformer un programme donné en un programme orienté objet - Banques
But:
|
Transformer un programme donné en un programme OO | |||
Thème:
|
Transformation d'un programme non OO en un programme OO, POO de base |
Le fichier Banque1.java contient un programme bancaire qui est modularisé sous forme de méthodes auxiliaires. Transformez-le en programme orienté objet sous le nom de Banque2.java en suivant les étapes suivantes :
- Etudiez le fonctionnement du programme. La banque a 2 clients. Chaque client a un compte privé et un compte d'épargne avec des soldes différents. Le taux d'intérêt d'un compte d'épargne est plus élevé que celui d'un compte privé. Les données de chaque client (nom, ville et soldes) sont affichées avant et après le bouclement des comptes.
- Réfléchissez aux objets que vous aimeriez utiliser dans votre programme et ajoutez les classes correspondantes. Il peut s'agir d'objets concrets (client, maison, billet, etc.) ou d'objets abstraits (compte, relation bancaire, etc.). N'oubliez pas que la modularisation n'est pas une science exacte. Chaque programmeur décide des classes qu'il trouve utiles pour son programme. C'est souvent l'étape la plus difficile d'un projet de programmation.
- Transférez le code concernant les objets dans les classes. Utilisez le mot-clé private pour encapsuler les variables et les méthodes d'instance qui ne seront pas utilisées à l'extérieur de la classe. Chaque méthode (auxiliaire ou d'instance) devrait être courte et sans trop d'instructions détaillées. Les identificateurs (noms des variables et des méthodes) devraient être parlants.
Exemple d'exécution du programme:
Données avant le bouclement des comptes:
Client Pedro de Genève
Compte privé: 1000.0 francs
Compte d'épargne: 2000.0 francs
Client Alexandra de Lausanne
Compte privé: 3000.0 francs
Compte d'épargne: 4000.0 francs
Données après le bouclement des comptes:
Client Pedro de Genève
Compte privé: 1010.0 francs
Compte d'épargne: 2040.0 francs
Client Alexandra de Lausanne
Compte privé: 3030.0 francs
Compte d'épargne: 4080.0 francs
Code donné:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
class Banque1 { public static void main(String args[]) { // Données pour tous les comptes privés (taux d'intérêt): double taux1 = 0.01; // Données pour tous les comptes d'épargne (taux d'intérêt): double taux2 = 0.02; // Données pour le premier client (nom et ville): String nom1 = "Pedro"; String ville1 = "Genève"; // Données pour le compte privé du premier client (solde): double solde1PremierClient = 1000.0; // Données pour le compte d'épargne du premier client (solde): double solde2PremierClient = 2000.0; // Données pour le deuxième client (nom et ville): String nom2 = "Alexandra"; String ville2 = "Lausanne"; // Données pour le compte privé du deuxième client (solde): double solde1DeuxiemeClient = 3000.0; // Données pour le compte d'épargne du deuxième client (solde): double solde2DeuxiemeClient = 4000.0; // Afficher les données du premier client: afficherClient(nom1, ville1, solde1PremierClient, solde2PremierClient); // Afficher les données du deuxième client: afficherClient(nom2, ville2, solde1DeuxiemeClient, solde2DeuxiemeClient); // Bouclement du compte privé du premier client: solde1PremierClient = bouclerCompte(solde1PremierClient, taux1); // Bouclement du compte d'épargne du premier client: solde2PremierClient = bouclerCompte(solde2PremierClient, taux2); // Bouclement du compte privé du deuxième client: solde1DeuxiemeClient = bouclerCompte(solde1DeuxiemeClient, taux1); // Bouclement du compte d'épargne du deuxième client: solde2DeuxiemeClient = bouclerCompte(solde2DeuxiemeClient, taux2); // Afficher les données du premier client: afficherClient(nom1, ville1, solde1PremierClient, solde2PremierClient); // Afficher les données du deuxième client: afficherClient(nom2, ville2, solde1DeuxiemeClient, solde2DeuxiemeClient); } static void afficherClient(String nom, String ville, double solde1, double solde2) { // Cette méthode affiche les données du client * System.out.println("Client " + nom + " de " + ville); System.out.println(" Compte privé: " + solde1 + " francs"); System.out.println(" Compte d'épargne: " + solde2 + " francs"); } static double bouclerCompte(double solde, double taux) { // Cette méthode ajoute les intérêts au solde */ double interets = taux * solde; double nouveauSolde = solde + interets; return nouveauSolde; } } |
Banque avec des clientes (Niveau 1)
Vous avez bien noté que l'affichage du programme Banque1 ne fait pas de différence entre les clientes et les clients. Ceci est facile à corriger dans la version orientée objets du programme, par exemple en ajoutant une variable d'instance booléenne masculin à la classe Client (si vous en avez une) et en testant sa valeur dans la méthode d'affichage. Modifiez votre programme, par exemple sous le nom de Banque3, pour qu'il affiche "cliente" au lieu de "client" comme suit:
Données avant le bouclement des comptes:
Client Pedro de Genève
Compte privé: 1000.0 francs
Compte d'épargne: 2000.0 francs
Cliente Alexandra de Lausanne
Compte privé: 3000.0 francs
Compte d'épargne: 4000.0 francs
Données après le bouclement des comptes:
Client Pedro de Genève
Compte privé: 1010.0 francs
Compte d'épargne: 2040.0 francs
Cliente Alexandra de Lausanne
Compte privé: 3030.0 francs
Compte d'épargne: 4080.0 francs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
class Banque2 { public static void main(String[] args) { // Variables locales pour les taux d'intérêts (afin d'éviter de // répéter les mêmes chiffres pour chaque client): double taux1 = 0.01; double taux2 = 0.02; // Construction des deux clients: Client c1 = new Client("Pedro", "Genève", taux1, 1000.0, taux2, 2000.0); Client c2 = new Client("Alexandra", "Lausanne", taux1, 3000.0, taux2, 4000.0); System.out.println("Données avant le bouclement des comptes:"); c1.afficher(); c2.afficher(); // Bouclement des comptes des deux clients: c1.boucler(); c2.boucler(); System.out.println("Données après le bouclement des comptes:"); c1.afficher(); c2.afficher(); } } class Client { private String nom; private String ville; private Compte cpt1, cpt2; public Client(String nom, String ville, double taux1, double solde1, double taux2, double solde2) { this.nom = nom; this.ville = ville; // Construction d'un compte privé: cpt1 = new Compte(taux1, solde1); // Construction d'un compte d'épargne: cpt2 = new Compte(taux2, solde2); } public void afficher() { // Cette méthode affiche les données du client System.out.println(" Client " + nom + " de " + ville); System.out.println(" Compte privé: " + cpt1.getSolde() + " francs"); System.out.println(" Compte d'épargne: " + cpt2.getSolde() + " francs"); } public void boucler() { // Cette méthode boucle les deux comptes du client cpt1.boucler(); cpt2.boucler(); } } class Compte { private double taux; private double solde; public Compte(double taux, double solde) { this.taux = taux; this.solde = solde; } public double getSolde() { return solde; } public void boucler() { // Cette méthode ajoute les intérêts au solde double interets = taux * solde; solde = solde + interets; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
class Banque3 { public static void main(String[] args) { // ... comme avant // Construction des deux clients, notez l'argument booléen: Client c1 = new Client("Pedro", "Genève", taux1, 1000.0, taux2, 2000.0, true); // Nouveau Client c2 = new Client("Alexandra", "Lausanne", taux1, 3000.0, taux2, 4000.0, false); // Nouveau // ... comme avant } } class Client { private String nom; private String ville; private Compte cpt1, cpt2; private boolean masculin; // Nouvelle variable d'instance // Méthode constructeur, notez le paramètre booléen: public Client(String nom, String ville, double taux1, double solde1, double taux2, double solde2, boolean masculin) { // Nouveau this.nom = nom; this.ville = ville; cpt1 = new Compte(taux1, solde1); cpt2 = new Compte(taux2, solde2); this.masculin = masculin; // Nouveau } public void afficher() { if (masculin) // Nouvelle instruction if..else System.out.print(" Client "); else System.out.print(" Cliente "); System.out.println(nom + " de " + ville); System.out.println(" Compte privé: " + cpt1.getSolde() + " francs"); System.out.println(" Compte d'épargne: " + cpt2.getSolde() + " francs"); } // ... comme avant } class Compte { // ... comme avant } |
class Banque2 {
public static void main(String[] args) {
// Variables locales pour les taux d'intérêts (afin d'éviter de
// répéter les mêmes chiffres pour chaque client):
double taux1 = 0.01;
double taux2 = 0.02;
// Construction des deux clients:
Client c1 = new Client("Pedro", "Genève", taux1, 1000.0, taux2, 2000.0);
Client c2 = new Client("Alexandra", "Lausanne", taux1, 3000.0, taux2, 4000.0);
System.out.println("Données avant le bouclement des comptes:");
c1.afficher();
c2.afficher();
// Bouclement des comptes des deux clients:
c1.boucler();
c2.boucler();
System.out.println("Données après le bouclement des comptes:");
c1.afficher();
c2.afficher();
}
}
class Client {
private String nom;
private String ville;
private Compte cpt1, cpt2;
public Client(String nom, String ville, double taux1, double solde1,
double taux2, double solde2) {
this.nom = nom;
this.ville = ville;
// Construction d'un compte privé:
cpt1 = new Compte(taux1, solde1);
// Construction d'un compte d'épargne:
cpt2 = new Compte(taux2, solde2);
}
public void afficher() {
// Cette méthode affiche les données du client
System.out.println(" Client " + nom + " de " + ville);
System.out.println(" Compte privé: " +
cpt1.getSolde() + " francs");
System.out.println(" Compte d'épargne: " +
cpt2.getSolde() + " francs");
}
public void boucler() {
// Cette méthode boucle les deux comptes du client
cpt1.boucler();
cpt2.boucler();
}
}
class Compte {
private double taux;
private double solde;
public Compte(double taux, double solde) {
this.taux = taux;
this.solde = solde;
}
public double getSolde() {
return solde;
}
public void boucler() {
// Cette méthode ajoute les intérêts au solde
double interets = taux * solde;
solde = solde + interets;
}
}
Exercice JAVA passage de parametres
But:
|
Que veut dire qu'une référence est passée par valeur ? | |||
Thème:
|
Passage de parametres | |||
|
Soit le programme suivant :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class ConcatIncorrecte { public static void main(String[] args) { String s = "China Blue"; System.out.println(s); concat(s, " Express"); System.out.println(s); } public static void concat(String s, String s2) { s +=s2; } } |
- Expliquez pourquoi la méthode concatener ne parvient pas à modifier la chaîne s du main (en y concaténant " Express")
- Corriger le codage de la méthode concatener et son utilisation dans le main de sorte à ce que l'exécution du programme affiche :
China Blue China Blue Express
au lieu de :China Blue China Blue
Fichiers:
|
ConcatIncorrecte.java |
Les explications et la correction sont données dans le code ci-dessous :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
class ConcatIncorrecte { public static void main(String[] args) { String s = "China Blue"; System.out.println(s); //version incorrecte //concatener(s, " Express"); // version correcte: s = concatener(s, " Express"); System.out.println(s); } /*les raisons du comportement incorrect sont que: 1. les opérations sur les chaines sont non destructives (créent une autre chaine au lieu d'agir sur la chaine originale) 2. l'objet s est une référence, mais les référence sont passées par valeur (on peut altérer l'objet référencé, mais pas la référence elle même): + crée une nouvelle chaine la référence de cette nouvelle chaine est affectée s (on essaie de changer la référence s et l'effet de cette modification n'est que local) (revoir l'exemple du cours "méthode auxilliaires et réutilisabilité" avec les tableaux) */ /* version incorrecte public static void concatener(String s,String s2 ) { s += s2; } */ // version corrigée public static String concatener(String s,String s2 ) { s += s2; return s; } } |
Exercice : tableau d’entiers
Dans cet exercice, on va travailler avec un tableau d’entiers initialisé:
1 i n t [ ] t a b = {12 , 15 , 13 , 10 , 8 , 9 , 13 , 1 4 } ;
On peut représenter graphiquement ce tableau comme suit:
0 1 2 3 4 5 6 7
12 15 13 10 8 9 13 14
Question 1 {sidebar id=1}
Ecrire un programme qui saisit un entier au clavier et qui recherche si cet entier appartient au tableau(réponse de type oui/non).
Question 2
Ecrire un programme qui saisit un entier au clavier et qui recherche si cet entier appartient au tableau. Au cas où la réponse est positive, l’indice de cet entier dans le tableau est affiché. S’il y a plusieurs occurrences,le dernier indice est affiché.
Question 3
Même question, mais s’il y a plusieurs occurrences, le premier indice est affiché.
Question 4
Ecrire un programme qui saisit un entier et un indice et met cet entier dans le tableau à cet indice. Il faudra vérifier que l’indice correspond bien à une case du tableau (par exemple 0 ou 3 sont corrects, mais -1 ou 123 ne sont pas des indices corrects pour ce tableau). Le programme affichera le contenu du tableau avant et après cette transformation.
Question 5
Ecrire un programme qui saisit deux indices et échange les valeurs contenues dans le tableau à ces deux indices. Le programme affichera le contenu du tableau avant et après cette transformation. Par exemple, si les deux indices saisit sont 1 et 5, le tableau après échange est:
0 1 2 3 4 5 6 7
12 9 13 10 8 15 13 14
Exercice : tableau entré au clavier
Question 1
Ecrire un programme qui saisit 6 entiers et les stocke dans un tableau, puis affiche le contenu de ce tableau une fois qu’il est rempli.
Question 2
Reprendre la partie saisie du programme précédent pour écrire un nouveau programme qui recherche et affiche le plus grand élément du tableau.
Question 3
Même question, c’est à dire saisie d’un tableau et recherche du plus grand élément, mais cette fois pour un tableau contenant des caractères.
Question 4
Ecrire un programme qui saisit un tableau de 6 entiers puis calcule la moyenne de ces six entiers. Attention, la moyenne des entiers n’est pas un entier.{sidebar id=8}
Question 5
Ecrire un programme qui saisit d’abord un nombre n, puis ensuite saisit n caractères et les place dans un tableau.
Exercice : nombre de lettres dans un tableau
Ecrire un programme qui saisit 10 caractères au clavier, puis ensuite, calcule le nombre de majuscules, et le nombre de lettres dans ce tableau. Un caractère n’est pas forcément une lettre: ce peut être un chiffre, un signe de ponctuation, un caractère spécial. Une majuscule est un caractère compris entre ’A’ et ’Z’ parce que l’ordre des caractères (utilisé notamment par les opérateurs , =) assure que toutes les lettres majuscules sont successives. De même une minuscule est un caractère compris entre ’a’ et ’z’. Pour cet exercice, pour simplifier le problème, on ne comptera pas les caractères avec des accents comme des lettres.
Exercice : somme des carrés
Ecrire une fonction qui calcule la somme des n premiers carrés 12 + 22 + . . . + n {sidebar id=8}
2. L’entier n est un paramètre de la fonction.
Exercice : sondage
Un institut de sondage veut faire une enquête sur les intentions de vote à un référendum. Il y a trois intentions possibles :
– voter oui
– voter non
– voter blanc ou s’abstenir
L’institut veut distinguer les intentions de vote des hommes et des femmes.
Le résultat du sondage sera donné sous la forme d’un tableau du genre :
oui | non | abstention | |
homme | 12 | 37 | 25 |
femme | 9 | 47 | 13 |
Ce tableau signifie par exemple que 12 hommes ont l’intention de voter oui, 37 de voter non, etc.
La représentation en Java d’un tel tableau se fera de la façon suivante :
0 1 2
12 | 37 | 25 |
9 | 47 | 13 |
{sidebar id=1}
Il y a donc un encodage où l’indice 0 signifie une intention de vote oui, l’indice 1 pour le non, l’indice 2 pour l’abstention, ainsi que l’indice 0 pour les hommes et l’indice 1 pour les femmes.
Ecrivez un programme qui lit au clavier un tel tableau et qui comporte les fonctions suivantes :
– une fonction qui calcule le nombre de femmes prises en compte dans l’enquête.
– une fonction qui calcule le nombre total de personnes ayant une intention de vote donnée. Cette intention de vote, de même que le tableau, sera un paramètre de la fonction. Elle pourra être donné sous forme de l’indice encodant cette intention.
– une fonction qui prédit le résultat du vote. Ce résultat ne prend pas en compte les abstentionnistes. Seuls les votes exprimés sont pris en compte (en France).
– une fonction qui détermine si les hommes et les femmes sont équitablement représentés dans l’enquête.
Exercice 3 : triangle (bis)
On rappelle le programme qui dessine des triangles faits avec des étoiles (exercice 6.2).
1 |
class Exo6_2{ |
Question 1
Adaptez ce programme pour qu’au lieu d’afficher les espaces et les étoiles à l’écran, il les mette dans
un tableau de caractères à deux dimensions. Le calcul du tableau sera fait dans une fonction qui prendra la
taille du triangle en paramètre.
Exemple de tableau avec une dimension 3 :
0 1 2 3 4
0 ’ ’ ’ ’ ’*’ ’ ’ ’ ’
1 ’ ’ ’*’ ’*’ ’*’ ’ ’
2 ’*’ ’*’ ’*’ ’*’ ’*’
Question 2
Ecrivez trois méthodes qui affichent un tableau contenant un triangle. La première doit afficher le triangle
avec la pointe en haut. La deuxième doit afficher la pointe à droite et la troisième, la pointe en bas.
pointe en haut * |
pointe à droite * |
pointe en bas ***** |
Exercice JAVA sur les opérateurs - expression polynômiale
But: On s'exerce un peu avec les opérateurs et les expressions arithmétiques de Java
Thème: Opérateurs et expressions
Écrivez un petit programme Java, Degre3.java, vous permettant d'évaluer un polynôme du 3ème degré de la forme:
((a+b)/2)x3 + (a+b)2x2 + a + b + c
Exemple d'exécution:
Entrez a (int) : 1 Entrez b (int) : 2 Entrez c (int) : 3 Entrez x (double) : 3.5 La valeur du polynôme est : 180.5625
Notez qu'il n'y a pas d'opérateur simple pour la puissance 3 en Java. Il faut utiliser des multiplications. Vous introduirez également au besoin des variables auxiliaires pour rendre le calcul plus efficace. N'oubliez pas de faire en sorte que le nom de la classe soit identique au nom du fichier.
Le but est d'écrire un petit programme permettant d'évaluer un polynôme du 3ème degré de la forme:
((a+b)/2)x3 + (a+b)2x2 + a + b + c
On commence par lire les coefficients du polynôme:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import java.util.Scanner; class Degre3 { private static Scanner scanner = new Scanner(System.in); public static void main(String[] args) { System.out.print("Entrez le coefficient a (int): "); int a = scanner.nextInt(); System.out.print("Entrez le coefficient b (int) "); int b = scanner.nextInt(); System.out.print("Entrez le coefficient c (int) "); int c = scanner.nextInt(); } } |
on fait pareil pour la variable, mais cette fois c'est un double:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import java.util.Scanner; class Degre3 { private static Scanner scanner = new Scanner(System.in); public static void main(String[] args) { System.out.print("Entrez le coefficient a (int): "); int a = scanner.nextInt(); System.out.print("Entrez le coefficient b (int) "); int b = scanner.nextInt(); System.out.print("Entrez le coefficient c (int) "); int c = scanner.nextInt(); System.out.print("Entrez la valeur de la variable x (double) "); double x = scanner.nextDouble(); } } |
Ensuite il faut coder la formule. On peut remarquer alors que a+b et x*x interviennent plusieurs fois dans le calcul. Pour éviter d'avoir à les recalculer deux fois, on peut les stocker dans des variables intermédiaires. On fait ensuite le calcul et on affiche le résultat:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import java.util.Scanner; class Degre3 { private static Scanner scanner = new Scanner(System.in); public static void main(String[] args) { System.out.print("Entrez le coefficient a (int) : "); int a = scanner.nextInt(); System.out.print("Entrez le coefficient b (int) : "); int b = scanner.nextInt(); System.out.print("Entrez le coefficient c (int) : "); double c = scanner.nextInt(); System.out.print("Entrez la valeur de la variable x (double) : "); double x = scanner.nextDouble(); double xx = x * x; double aux = a + b; double valeur = aux/2 * x * xx + aux * aux * xx + aux +c; System.out.println("La valeur de l'expression est: " + valeur); } } |
Attention! Pour que le calcul de (a+b)/2 se fasse correctement (sans troncature due à la division entière), il est indispensable que la variable intermédiaire aux soit déclarée comme double.
Exercice sur la récursivité JAVA : calculer le factorielle
But:
Calcul récursif et itératif de la factorielle de n.
Récursivité
Pour calculer n! (factorielle n), on peut utiliser deux formules différentes :
- La formule itérative :
n! = 1 * 2 * 3 * ... * n |
- La formule récursive définissant n! en fonction de
(n-1)! :
0! (factorielle de zéro) = 1 |
pour tout entier n>0, n! = n * (n-1)! |
Dans le fichier Factorielle.java, définissez deux méthodes factorielleRecursive et factorielleIterative implémentant les deux méthodes de calcul décrites précédemment. La calcul devra se faire sur des entiers compris entre 0 et 12 introduits par l'utilisateur. Une méthode demanderNombre redemandera le nombre à l'utilisateur tant que celui-ci ne sera pas compris dans l'intervalle souhaité.
Implémentez ensuite la méthode main qui demandera un nombre à l'utilisateur et calculera la factorielle de ce nombre des deux manière possibles.
Pour terminer, ajouter une boucle demandant à l'utilisateur s'il souhaite recommencer.
Exemple de déroulement
Entrez un nombre entier compris entre 0 et 12 : 12 Méthode itérative : 12! = 479001600 Méthode récursive : 12! = 479001600 Voulez-vous recommencer [o/n] ? o Entrez un nombre entier compris entre 0 et 12 : 6 Méthode itérative : 6! = 720 Méthode récursive : 6! = 720 Voulez-vous recommencer [o/n] ? n
Factorielle.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
import java.util.Scanner; class Factorielle { private static Scanner scanner = new Scanner(System.in); public static void main(String[] args) { char recommencer = 'o'; do { int n = demanderNombre(); System.out.println("Méthode itérative :"); System.out.println(n + "! = " + factorielleIterative(n)); System.out.println("Méthode recursive :"); System.out.println(n + "! = " + factorielleRecursive(n)); System.out.println("Voulez-vous recommencer [o/n] ?"); recommencer = scanner.next().charAt(0); } while (recommencer == 'o'); } /** * Demande un entier à l'utilisateur * @return L'entier entré par l'utilisateur */ static int demanderNombre() { int n; do { System.out.println("Donnez un nombre entier compris entre 0 et 12 (compris)"); n = scanner.nextInt(); } while ((n > 12) || (n < 0)); return n; } /** * Calcul de la factorielle par la méthode itérative * @param nombre Le nombre dont on veut calculer la factorielle * @return nombre! */ static int factorielleIterative(int nombre) { int fact = 1; for (int i = 2; i <= nombre; i++) { fact *= i; } return fact; } /** * Calcul de la factorielle par la méthode récursive * @param nombre Le nombre dont on veut calculer la factorielle * @return nombre! */ static int factorielleRecursive(int nombre) { if (nombre == 0) { return 1; } else { return (nombre * factorielleRecursive(nombre - 1)); } } } |
Exercice JAVA permutation du contenu de deux variables
Implémentez en Java un algorithme vous permettant de permuter les valeurs de deux variables
Exemple d'exécution:
Entrez x: 1 Entrez y: 2 Avant permutation: x : 1 y : 2 Après permutation: x : 2 y : 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import java.util.Scanner; class Permutation { private static Scanner scanner = new Scanner(System.in); public static void main(String[] args) { System.out.print("Entrez x: "); int x = scanner.nextInt(); System.out.print("Entrez y: "); int y = scanner.nextInt(); System.out.println("Avant permutation: "); System.out.println("x : " + x); System.out.println("y : " + y); int tmp = x; x = y; y = tmp; System.out.println("Après permutation: "); System.out.println("x : " + x); System.out.println("y : " + y); } } |
Exerice PGCD
But:
|
Ecrivez un programme qui calcule le plus grand diviseur commun de deux nombres entiers | |||
Thème:
|
Algorithme, if, boucles |
Ecrivez un programme PGDC.java qui calcule et affiche le plus grand diviseur commun de deux nombres entiers positifs entrés au clavier. Exemples d'exécution du programme:
Entrez un nombre positif : 9
Entrez un nombre positif : 6
Le plus grand diviseur commun de 9 et 6 est 3
Entrez un nombre positif : 9
Entrez un nombre positif : 4
Le plus grand diviseur commun de 9 et 4 est 1
Utilisez la formule d'Euclide pour déterminer le plus grand diviseur. Cette formule se résume comme suit:
Soient deux nombres entiers positifs a et b. Si a est plus grand que b, le plus grand diviseur commun de a et b est le même que pour a-b et b. Vice versa si b est plus grand que a.
Les équivalences mathématiques utiles sont:
- Si a > b, alors PGDC(a, b) = PGDC(a-b, b)
- PGDC(a, a) = a
Exemple de calcul de PGDC(42, 24):
- 42 > 24, alors PGDC(42, 24) = PGDC(42--24, 24) = PGDC(18, 24) = PGDC(24,18)
- 24 > 18, alors PGDC(24, 18) = PGDC(24--18, 18) = PGDC(6, 18) = PGDC(18, 6)
- 18 > 6, alors PGDC(18, 6) = PGDC(18--6, 6) = PGDC(12, 6)
- 12 > 6, alors PGDC(12, 6) = PGDC(12--6, 6) = PGDC(6, 6)
- Résultat: PGDC(42, 24) = PGDC(6, 6) = 6
Indication: utilisez une boucle (par exemple while) qui s'occupe de modifier et de tester les valeurs de a et b jusqu'à ce qu'une solution soit trouvée.
1 |
import java.util.Scanner; |
Exercice JAVA condition if - nombre pair ou impair
But: Un programme qui indique si un nombre est pair ou impair.
Thème: if
Ecrivez un programme Java qui lit un nombre et indique s'il est positif, négatif ou s'il vaut zéro et s'il est pair ou impair.
Exemple d'exécution:
Entrez un nombre entier: 5 Le nombre est positif et impair Entrez un nombre entier: -4 Le nombre est négatif et pair Entrez un nombre entier: 0 Le nombre est zéro (et il est pair)
Dans cette exercice, le test sur la parité d'un nombre se fait en examinant le reste de la division entière (opérateur %) par 2: si ce reste est nul le nombre est pair. Les tests nécessaires pour vérifier la parité d'un nombre seront faits au moyen de if imbriqués. Dans la ligne 12, on teste si le nombre est nul (c'est le cas le plus simple). Si ce n'est pas le cas nous faisons un premier test pour savoir si le nombre est positif ou négatif (lignes 18 - 23), puis s'il est pair ou impair (lignes 28 - 32).