Donner l'affichage produit par le programme suivant :
public class Exo11 {
public static void main(String[] args) {
int i = 2;
int j = 4;
int k = 0;
for (; k < j + 1; k++) {
System.out.println(k + " " + i + " " + j);
i = i + 1;
if (i % 2 == 0) {
j = j - 1;
}
}
System.out.println(k + " " + i + " " + j);
}
}
On obtient l'affichage suivant :
0 2 4 1 3 4 2 4 3 3 5 3 4 6 2
Donner l'affichage produit par le programme suivant :
public class Exo21 {
public static void main(String[] args) {
int u = 1;
int v = 2;
while (u < v) {
System.out.println("(" + u + ", " + v + ")");
u = u + 1;
if (u % 2 == 0) {
v = v + 1;
} else {
if (u % 3 == 0) {
v = v + 2;
}
}
}
System.out.println("(" + u + ", " + v + ")");
}
}
On obtient l'affichage suivant :
(1, 2) (2, 3) (3, 5) (4, 6) (5, 6) (6, 7) (7, 7)
Donner l'affichage produit par le programme suivant :
import java.util.Arrays;
public class Exo31 {
public static void main(String[] args) {
int[] x = { 5, 6, 7 };
int[] y = new int[x.length + 1];
System.out.println(y);
int k = 0;
for (int z : x) {
y[k] = z;
k = k + 1;
}
y[k] = k;
System.out.println(Arrays.toString(y));
int j = x.length - 1;
while (j > 0) {
x[j] = x[j] + j + 1;
j = j - 1;
System.out.println(j + " <-> " + x[j]);
}
System.out.println(Arrays.toString(x));
}
}
On obtient l'affichage suivant :
[I@6950ecc7 [5, 6, 7, 3] 1 <-> 6 0 <-> 5 [5, 8, 10]
import java.util.Arrays;
public class Exo41 {
public static void main(String[] args) {
int[] x = new int[À COMPLÉTER];
int j = À COMPLÉTER;
for (int i = 0; i < x.length; i++) {
j = À COMPLÉTER;
x[i] = j;
}
System.out.println(Arrays.toString(x));
int z = À COMPLÉTER;
for (int y : x) {
z = À COMPLÉTER;
}
System.out.println(z);
}
}
Compléter le programme ci dessus pour qu'il affiche :
[2, 4, 8, 16] 30
Indice \(30 = 2 + 4 + 8 + 16\)
On peut utiliser le programme suivant :
import java.util.Arrays;
public class Exo41 {
public static void main(String[] args) {
int[] x = new int[4];
int j = 1;
for (int i = 0; i < x.length; i++) {
j = j * 2;
x[i] = j;
}
System.out.println(Arrays.toString(x));
int z = 0;
for (int y : x) {
z = z + y;
}
System.out.println(z);
}
}
Donner l'affichage produit par le programme suivant :
class Exo51 {
private StringBuilder x;
public Exo51() {
x = new StringBuilder(); // chaîne vide
}
public Exo51 plop(char c) {
x.append(c); // ajout à la fin
return this;
}
public Exo51 foo(char c) {
x.insert(0, c); // insertion au début
return this;
}
public String toString() {
return "[" + x + "]";
}
}
public class TestExo51 {
public static void main(String[] args) {
String s = "ABCD";
Exo51 arf = new Exo51();
System.out.println(arf);
for (int i = 0; i < s.length(); i++) {
System.out.println(arf.foo(s.charAt(i)));
}
Exo51 bla = new Exo51();
for (int i = 0; i < s.length(); i++) {
if (i % 2 == 0) {
bla.foo(s.charAt(i));
bla.plop(s.charAt(s.length() - i - 1));
} else {
bla.plop(s.charAt(i));
bla.foo(s.charAt(s.length() - i - 1));
}
System.out.println(bla);
}
}
}
On obtient l'affichage suivant :
[] [A] [BA] [CBA] [DCBA] [AD] [CADB] [CCADBB] [ACCADBBD]
Modifier la classe Exo51 pour rendre ses instances immuables.
Une solution possible est la suivante :
public class Exo51 {
private StringBuilder x;
public Exo51() {
x = new StringBuilder(); // chaîne vide
}
public Exo51 plop(char c) {
Exo51 res = new Exo51();
// on ajoute x à la fin du x de res ce qui
// revient à le copier
res.x.append(x);
// puis on ajoute le caractère
res.x.append(c);
// this.x n'est pas modifié par ces deux opérations
return res;
}
public Exo51 foo(char c) {
Exo51 res = new Exo51();
// on commence par insérer c au début par un simple
// ajout
res.x.append(c);
// puis on ajoute le x de l'objet appelant
res.x.append(x);
return res;
}
public String toString() {
return "[" + x + "]";
}
}
Donner les modifications minimales de la méthode main pour obtenir le même affichage avec les objets immuables.
Une solution possible est la suivante :
public class TestExo51 {
public static void main(String[] args) {
String s = "ABCD";
Exo51 arf = new Exo51();
System.out.println(arf);
for (int i = 0; i < s.length(); i++) {
// immuable, donc il faut récupérer l'objet créé
arf = arf.foo(s.charAt(i));
System.out.println(arf);
}
Exo51 bla = new Exo51();
for (int i = 0; i < s.length(); i++) {
// ici aussi
if (i % 2 == 0) {
bla = bla.foo(s.charAt(i));
bla = bla.plop(s.charAt(s.length() - i - 1));
} else {
bla = bla.plop(s.charAt(i));
bla = bla.foo(s.charAt(s.length() - i - 1));
}
System.out.println(bla);
}
}
}
Donner l'affichage produit par le programme suivant :
class Exo61 {
private int n;
private double[] x;
public Exo61(int p) {
x = new double[p];
n = 0;
}
public double f() {
if (n > 0) {
n = n - 1;
return x[n];
} else {
// valeur spéciale qui s'affiche NaN
return Double.NaN;
}
}
public boolean g(double y) {
if (n < x.length) {
x[n] = y;
n = n + 1;
return true;
} else {
return false;
}
}
}
public class TestExo61 {
public static void main(String[] args) {
Exo61 t = new Exo61(3);
for (int i = 0; i < 4; i++) {
System.out.println(t.g(i * 2.0));
}
for (int i = 0; i < 4; i++) {
System.out.println(t.f());
}
Exo61 u = new Exo61(2);
Exo61 v = new Exo61(2);
double[] x = { 2.0, -2.5, 4.0, 1.5 };
for (double y : x) {
if (!u.g(y)) {
v.g(-y);
}
}
for (int i = 0; i < 3; i++) {
System.out.println(u.f() + " " + v.f());
}
}
}
On obtient l'affichage suivant :
true true true false 4.0 2.0 0.0 NaN -2.5 -1.5 2.0 -4.0 NaN NaN
class Exo71 {
private À COMPLÉTER;
private À COMPLÉTER;
public Exo71(À COMPLÉTER) {
À COMPLÉTER
}
@Override
public String toString() {
À COMPLÉTER
}
public double insert(double x) {
double res = x;
À COMPLÉTER
return res;
}
}
public class TestExo71 {
public static void main(String[] args) {
Exo71 u = new Exo71(0, 1);
System.out.println(u);
System.out.println(u.insert(0.5));
System.out.println(u);
System.out.println(u.insert(1.5));
System.out.println(u);
System.out.println(u.insert(-0.5));
System.out.println(u);
System.out.println(u.insert(1.0));
System.out.println(u);
}
}
Compléter le programme ci dessus pour qu'il affiche :
[0.0, 1.0] 0.5 [0.0, 1.0] 1.0 [0.0, 1.5] 0.0 [-0.5, 1.5] 1.0 [-0.5, 1.5]
Une solution possible est la suivante :
public class Exo71 {
private double min;
private double max;
public Exo71(double min, double max) {
this.min = min;
this.max = max;
}
@Override
public String toString() {
return "[" + min + ", " + max + "]";
}
public double insert(double x) {
double res = x;
if (x < min) {
res = min;
min = x;
} else if (x > max) {
res = max;
max = x;
}
return res;
}
}
Modifier la classe Exo71
pour que ses instances soient immuables, sans changer
significativement son comportement. Attention, il faut obligatoirement
changer le type du résultat de la méthode insert
et ajouter une autre
méthode.
La difficulté vient du fait que la méthode insert
modifie l'objet appelant
et renvoie en plus une valeur. Or, la technique classique pour rendre des
objets immuables consiste à faire renvoyer par chaque méthode un nouvel objet
plutôt que de modifier l'objet appelant. Ici, il faut donc renvoyer deux
choses, d'une part le nouvel objet et d'autre part le résultat de la
méthode. Pour ce faire, on ajoute à l'objet une variable d'instance destinée
à recevoir le résultat de la méthode insert
(dans la version
modifiable). La nouvelle méthode insert
renvoie comme d'habitude un nouvel
objet. Ce dernier possède une méthode getValue
qui permet d'obtenir la
valeur numérique (le résultat) que renvoyait la méthode insert
dans la
version modifiable. On obtient ainsi :
class Exo71 {
private double min;
private double max;
// cette variable contient la valeur
// renvoyée par insert dans la version
// modifiable
private double value;
public Exo71(double min, double max) {
this.min = min;
this.max = max;
// initialisation à une valeur arbitraire
this.value = Double.NaN;
}
@Override
public String toString() {
return "[" + min + ", " + max + "]";
}
public double getValue() {
return value;
}
public Exo71 insert(double x) {
Exo71 result = new Exo71(min,max);
result.value = x;
if (x < min) {
result.value = min;
result.min = x;
} else if (x > max) {
result.value = max;
result.max = x;
}
return result;
}
}
public class TestExo71 {
public static void main(String[] args) {
Exo71 u = new Exo71(0, 1);
System.out.println(u);
u = u.insert(0.5);
System.out.println(u.getValue());
System.out.println(u);
u = u.insert(1.5);
System.out.println(u.getValue());
System.out.println(u);
u = u.insert(-0.5);
System.out.println(u.getValue());
System.out.println(u);
u = u.insert(1.0);
System.out.println(u.getValue());
System.out.println(u);
}
}
Donner l'affichage produit par le programme suivant :
class A81 {
private int x;
public A81() {
x = 1;
}
public int f() {
return x;
}
}
class B81 extends A81 {
@Override
public String toString() {
return String.valueOf(f());
}
public int g() {
return 3;
}
}
class C81 extends B81 {
@Override
public int f() {
return 2;
}
}
public class Test81 {
public static void main(String[] args) {
A81 x = new A81();
System.out.println(x + " || " + x.f());
B81 y = new B81();
System.out.println(y + " || " + y.f() + " || " + y.g());
C81 z = new C81();
System.out.println(z + " || " + z.f() + " || " + z.g());
x = z;
System.out.println(x + " || " + x.f());
y = z;
System.out.println(y + " || " + y.f() + " || " + y.g());
Object o = z;
System.out.println(o);
}
}
On obtient l'affichage suivant :
A81@56833a2e || 1 1 || 1 || 3 2 || 2 || 3 2 || 2 2 || 2 || 3 2
Si on ajoute System.out.println(x.g());
juste après la ligne
System.out.println(o);
(dernière de la méthode main
), le programme ne
compile plus. Expliquer brièvement pourquoi.
Il s'agit d'un problème classique d'héritage. En effet, x
est une variable
de type A81
. De ce fait, quel que soit l'objet que x
désigne, le
programme ne peut appeler que des méthodes définies dans la classe A81
. Or,
la méthode g
n'est pas définie dans cette classe et le programme n'est donc
pas correct.
Donner l'affichage produit par le programme suivant :
class Exo101 {
private int x;
private int y;
private int w;
public Exo101(int w) {
this.w = w;
x = 0;
y = 0;
}
public int foo() {
x = x + 1;
if (x > w) {
x = 0;
y = y + 1;
}
return x;
}
public int bar() {
x = x - 1;
int res = x;
if (x < 0) {
x = 0;
y = y - 1;
}
return res;
}
@Override
public String toString() {
return x + " [" + y + "]";
}
}
public class TestExo101 {
public static void main(String[] args) {
Exo101 robert = new Exo101(3);
System.out.println(robert);
System.out.println(robert.foo());
System.out.println(robert);
System.out.println(robert.bar());
System.out.println(robert);
Exo101 hank = new Exo101(2);
Exo101 charlie = hank;
for (int i = 0; i < 5; i++) {
System.out.println(hank.foo());
System.out.println(hank);
}
System.out.println(charlie);
}
}
On obtient l'affichage suivant :
0 [0] 1 1 [0] 0 0 [0] 1 1 [0] 2 2 [0] 0 0 [1] 1 1 [1] 2 2 [1] 2 [1]
Un objet de la classe Rectangle
représente un rectangle (fermé) du
plan. Le rectangle est décrit par son coin inférieur gauche (de coordonnées
x
et y
), sa largeur w
et sa hauteur h
(cf
la figure ci dessous).
L'objectif de l'exercice est de compléter la classe ci-dessous de la façon suivante :
largeur
renvoie la largeur du rectangle ;hauteur
renvoie la hauteur du rectangle ;xMax
renvoie l'abscisse du coin supérieur droit du
rectangle ;yMax
renvoie l'ordonnée du coin supérieur droit du
rectangle ;contient
renvoie true
si
le point de coordonnées x,y
est contenu dans le rectangle appelant
(et false
sinon) ;toString
représente le rectangle sous la forme d'un
produit d'intervalles [a,b]x[c,d]
;intersecte
renvoie true
si le rectangle
appelant et le rectangle that
ont une intersection non vide (et
false
sinon) ;intersection
renvoie un nouveau rectangle
représentant l'intersection entre le rectangle appelant et un rectangle
paramètre (vous devez écrire cette méthode complètement).public class Rectangle {
private double x;
private double y;
private double w; // largeur
private double h; // hauteur
public Rectangle(double x, double y, double w, double h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
public double largeur() {
À COMPLÉTER
}
public double hauteur() {
À COMPLÉTER
}
public double xMax() {
À COMPLÉTER
}
public double yMax() {
À COMPLÉTER
}
@Override
public String toString() {
À COMPLÉTER
}
public boolean contient(double u, double v) {
À COMPLÉTER
}
public boolean intersecte(Rectangle that) {
À COMPLÉTER
}
}
Une solution possible est la classe suivante :
public class Rectangle {
private double x;
private double y;
private double w; // largeur
private double h; // hauteur
public Rectangle(double x, double y, double w, double h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
public double largeur() {
return w;
}
public double hauteur() {
return h;
}
public double xMax() {
return x + w;
}
public double yMax() {
return y + h;
}
public boolean contient(double u, double v) {
return x <= u && u - x <= w && y <= v && v - y <= h;
}
@Override
public String toString() {
return "[" + x + ", " + (x + w) + "] x [" + y + ", " + (y + h) + "]";
}
public boolean intersecte(Rectangle that) {
return contient(that.x, that.y) || contient(that.x + that.w, that.y) || contient(that.x, that.y + that.h)
|| contient(that.x + that.w, that.y + that.h);
}
}