Affichage 1

Quel est l'affichage produit par le programme suivant :

public class Exo11 { // Affichage (1)
    public static void main(String[] args) {
	String s = "";
	int i = 2;
	int j = 3;
	for (int k = 0; k < 5; k++) {
	    s = s + k;
	    System.out.println(i + ", " + j);
	    i += 2;
	    for (int u = 0; u < s.length(); u++) {
		j = j + u % 2;
	    }
	    System.out.println(s);
	    if (j > 4) {
		i = i - 1;
			}
	}
    }
}

On obtient l'affichage suivant :

2, 3
0
4, 3
01
6, 4
012
7, 5
0123
8, 7
01234

Affichage 2

Quel est l'affichage produit par le programme suivant :

import java.util.Arrays;

public class Exo21 { // Affichage (2)
    public static void main(String[] args) {
	int[] u = new int[4];
	for (int i = 0; i < u.length; i++) {
	    u[i] = 2 * i + 1;
	}
	System.out.println(u);
	boolean[] v = new boolean[u.length + 1];
	v[0] = true;
	int j = 1;
	for (int i = 0; i < u.length; i++) {
	    v[i + 1] = u[i] > j;
	    if (v[i]) {
		j = j + 2;
	    }
	}
	System.out.println(j);
	System.out.println(Arrays.toString(v));
	int m = 4;
	for(int k: u) {
	    k = k - 1;
	    System.out.println(k);
	    v[m] = !v[m];
	    m--;
	}
	System.out.println(Arrays.toString(u));
	System.out.println(Arrays.toString(v));
    }
}

On obtient l'affichage suivant :

[I@659e0bfd
5
[true, false, false, true, true]
0
2
4
6
[1, 3, 5, 7]
[true, true, true, false, false]

Programmation 1

Écrire un programme complet qui réalise les opérations suivantes :

  1. demande à l'utilisateur une valeur entière \(k\) ;
  2. affiche la valeur de \(u_j=\sum_{i=1}^j(2i+1)\) pour \(j\) allant de \(k\) à \(1\) dans l'ordre décroissant de \(j\). Pour \(k=2\), on affichera ainsi :
u_2 = 8
u_1 = 3

Une solution possible est donnée par le programme suivant :

import java.util.Scanner;

public class Calcul {
    public static void main(String[] args) {
	Scanner scan = new Scanner(System.in);
	System.out.print("k= ");
	int k = scan.nextInt();
	int[] results = new int[k];
	results[0] = 3;
	for (int i = 2; i <= k; i++) {
	    results[i - 1] = results[i - 2] + (2 * i + 1);
	}
	for (int i = k; i >= 1; i--) {
	    System.out.printf("u_%d = %d%n", i, results[i - 1]);
	}
    }
}

Affichage 3

Quel est l'affichage produit par le programme suivant :

import java.util.Arrays;

public class Exo31 { // Affichage (3)

    public static void main(String[] args) {
	int[][] bla = new int[2][];
	int[][] foo = new int[2][];
	for (int i = 0; i < bla.length; i++) {
	    int[] sub = new int[i + 2];
	    for (int j = 0; j < sub.length; j++) {
		sub[j] = j + i + 1;
	    }
	    System.out.println(Arrays.toString(sub));
	    bla[i] = sub;
	    foo[bla.length - i - 1] = sub;
	}
	System.out.println(Arrays.deepToString(bla));
	System.out.println(Arrays.deepToString(foo));
	bla[1][1] = bla[1][1] + 2;
	int[] pouic = foo[1];
	foo[1] = new int[] { 0, 1, 6 };
	foo[1][0] = -1;
	bla[0][1] = -2;
	System.out.println(Arrays.deepToString(bla));
	System.out.println(Arrays.deepToString(foo));
	System.out.println(Arrays.toString(pouic));
    }

}

On obtient l'affichage suivant :

[1, 2]
[2, 3, 4]
[[1, 2], [2, 3, 4]]
[[2, 3, 4], [1, 2]]
[[1, -2], [2, 5, 4]]
[[2, 5, 4], [-1, 1, 6]]
[1, -2]

Programmation 2

Écrire un programme qui réalise les opérations suivantes (on pourra se contenter de donner le contenu de la méthode main) :

  1. demande à l'utilisateur deux valeurs entières \(k\) et \(j\) ;
  2. crée un tableau à deux dimensions de taille \(k\times j\) ;
  3. place dans la case \([k][j]\) du tableau le nombre réel \(\sqrt{k^2+j^2}\) (on rappelle que la méthode Math.sqrt permet le calcul d'une racine carrée) ;
  4. affiche les lignes du tableau une par une, sans utiliser les méthodes Arrays.toString et Arrays.deepToString. Attention, on souhaite un passage à la ligne seulement à la fin d'une ligne du tableau, pas après chaque nombre. Les nombres d'une ligne seront séparés par le signe de ponctuation deux points (\(:\)).

Une solution possible est donnée par le programme suivant :

import java.util.Scanner;

public class Tableau {
    public static void main(String[] args) {
	Scanner scan = new Scanner(System.in);
	System.out.print("k = ");
	int k = scan.nextInt();
	System.out.print("j = ");
	int j = scan.nextInt();
	double[][] tab = new double[k][j];
	for (int i = 0; i < k; i++) {
	    for (int l = 0; l < j; l++) {
		tab[i][l] = Math.sqrt(i * i + l * l);
	    }
	}
	for (int i = 0; i < k; i++) {
	    for (int l = 0; l < j - 1; l++) {
		System.out.print(tab[i][l]+":");
	    }
	    System.out.println(tab[i][j-1]);
	}
    }
}

Affichage 4

Quel est l'affichage produit par le programme suivant :

import java.math.BigInteger;

class Exo41 { // Affichage (4)
    private BigInteger x;

    private StringBuilder y;

    public Exo41(int z) {
	x = BigInteger.valueOf(z);
	y = new StringBuilder(x.toString());
    }

    public void plop(int z) {
	x = x.add(BigInteger.valueOf(z));
	y = y.append(z);
    }

    public void foo(Exo41 that) {
	x = that.x.add(x);
	y = y.append(that.y);
    }

    public long getX() {
	return x.longValue();
    }

    @Override
    public String toString() {
	return y.toString();
    }
}

public class TestExo41 {
    public static void main(String[] args) {
	Exo41 a = new Exo41(3);
	System.out.println(a);
	Exo41 b = new Exo41(3);
	Exo41 c = a;
	String s = c.toString();
	a.plop(2);
	System.out.println(a);
	System.out.println(b + " " + c + " " + s);
	Exo41 d = new Exo41(45);
	Exo41 e = d;
	b.foo(d);
	System.out.println(b + " " + d + " " + e);
	Exo41 f = new Exo41(0);
	while (f.getX() < 4) {
	    f.plop(1);
	    System.out.println(f);
	}
    }
}

On obtient l'affichage suivant :

3
32
3 32 3
345 45 45
01
011
0111
01111

Programmation 3

  1. Modifiez la classe Exo41 de l'exercice précédent pour rendre ses instances immuables en gardant le même comportement général. Vous pouvez vous contenter d'écrire les parties modifiées, sans recopier ce qui ne change pas.
  2. Modifiez la méthode main de la classe TestExo41 pour qu'elle donne exactement le même affichage que la version actuelle mais en utilisant la version immuable de Exo41.

Une solution possible est donnée par le programme suivant :

import java.math.BigInteger;

class Exo41Immuable { 
    private BigInteger x;

    private StringBuilder y;

    public Exo41Immuable(int z) {
	x = BigInteger.valueOf(z);
	y = new StringBuilder(x.toString());
    }

    private Exo41Immuable(BigInteger x, StringBuilder y) {
	this.x = x;
	this.y = y;
    }

    public Exo41Immuable plop(int z) {
	StringBuilder ny=new StringBuilder(y.toString());
	ny.append(z);
	return new Exo41Immuable(x.add(BigInteger.valueOf(z)), ny);
    }

    public Exo41Immuable foo(Exo41Immuable that) {
	StringBuilder ny=new StringBuilder(y.toString());
	ny.append(that.y);
	return new Exo41Immuable(that.x.add(x), ny);
    }

    public long getX() {
	return x.longValue();
    }

    @Override
    public String toString() {
	return y.toString();
    }
}
public class TestExo41Immuable {
    public static void main(String[] args) {
	Exo41Immuable a = new Exo41Immuable(3);
	System.out.println(a);
	Exo41Immuable b = new Exo41Immuable(3);
	Exo41Immuable c = a;
	String s = c.toString();
	a = a.plop(2);
	System.out.println(a);
	System.out.println(b + " " + c + " " + s);
	Exo41Immuable d = new Exo41Immuable(45);
	Exo41Immuable e = d;
	b = b.foo(d);
	System.out.println(b + " " + d + " " + e);
	Exo41Immuable f = new Exo41Immuable(0);
	while (f.getX() < 4) {
	    f = f.plop(1);
	    System.out.println(f);
	}
    }
}

L'affichage n'est pas strictement identique en raison de l'absence d'effet de bord. On obtient en effet :

3
32
3 3 3
345 45 45
01
011
0111
01111

Pour obtenir exactement le même affichage, il faut remplacer l'instruction System.out.println(b + " " + c + " " + s); par System.out.println(b + " " + a + " " + s);.

Programmation 4

Question 1

Un objet de la classe Compteur représente un compteur qui peut prendre des valeurs entières entre 0 et max. Les objets de cette classe sont immuables. Compléter le programme suivant en fonction des commentaires :

public class Compteur {
    // ajouter les variables nécessaires

    public Compteur(int max) {
	// le compteur est initialisé à zéro
	// sa valeur maximale possible est max
    }

    public int valeur() {
	// renvoie la valeur du Compteur appelant
    }

    public boolean estMax() {
	// renvoie true si et seulement si la valeur maximale est atteinte
    }

    public Compteur incrémente() {
	// renvoie un nouveau Compteur dont la valeur est n+1 si la valeur du 
	// Compteur appelant est n, sauf si n vaut max. Si n vaut max, la valeur
	// reste la même
    }

    public Compteur reset() {
	// renvoie un nouveau Compteur dont la valeur est 0
    }

    @Override
    public String toString() {
	// représentation du Compteur sous la forme "valeur [max]"
    }
}

Une solution possible est donnée par le programme suivant :

public class Compteur {
    private int max;

    private int valeur;

    public Compteur(int max) {
	valeur = 0;
	this.max = max;
    }

    public int valeur() {
	return valeur;
    }

    public boolean estMax() {
	return valeur == max;
    }

    public Compteur incrémente() {
	if (estMax()) {
	    return this;
	} else {
	    Compteur res = new Compteur(max);
	    res.valeur = valeur + 1;
	    return res;
	}
    }

    public Compteur reset() {
	return new Compteur(max);
    }

    @Override
    public String toString() {
	return valeur + "[" + max + "]";
    }
}

Question 2

Proposer une version modifiable de cette classe en adaptant les définitions des méthodes à cette situation. On se contentera de donner les méthodes différentes de celles de la version immuable.

Une solution possible est donnée par le programme suivant :

public class Compteur {
    private int max;

    private int valeur;

    public Compteur(int max) {
	valeur = 0;
	this.max = max;
    }

    public int valeur() {
	return valeur;
    }

    public boolean estMax() {
	return valeur == max;
    }

    public void incrémente() {
	if (!estMax()) {
	    valeur ++;
	} 
    }

    public void reset() {
	valeur = 0;
    }

    @Override
    public String toString() {
	return valeur + "[" + max + "]";
    }
}

Affichage 5

Quel est l'affichage produit par le programme suivant :

class A1 { // Affichage (5)
    private int x;

    public A1(int x) {
	this.x = x;
    }

    public int foo() {
	return 2 * x;
    }

    public B1 bar(B1 that) {
	x = x - 2 * that.bar();
	B1 res = new B1(x);
	return res;
    }

    @Override
    public String toString() {
	return "A1@" + x;
    }
}

class B1 {
    private int x;

    public B1(int x) {
	this.x = x + 1;
    }

    public void foo(A1 that) {
	x = x - that.foo();
    }

    public int bar() {
	return -x;
    }

    @Override
    public String toString() {
	return "B1@" + x;
    }
}

public class TestAB1 {

    public static void main(String[] args) {
	A1 a = new A1(2);
	B1 b = new B1(4);
	System.out.println(a + " " + b);
	b.foo(a);
	System.out.println(a + " " + b);
	a = new A1(1);
	b = new B1(3);
	a.bar(b);
	System.out.println(a + " " + b);
	B1 c = a.bar(b);
	System.out.println(a + " " + b + " " + c);
	a = new A1(3);
	b = new B1(1);
	b = a.bar(a.bar(b));
	System.out.println(a + " " + b);                
    }

}

On obtient l'affichage suivant :

A1@2 B1@5
A1@2 B1@1
A1@9 B1@4
A1@17 B1@4 B1@18
A1@23 B1@24

Affichage 6

On donne les classes suivantes :

public class A1 {
	protected int x;
	public A1(int x) {
		this.x = x;
	}
	public int f() {
		return x + 1;
	}
	@Override
	public String toString() {
		return "[" + x + "]";
	}
}

public class B1 extends A1 {
	public B1(int x) {
		super(x);
	}
	@Override
	public int f() {
		return x + 2;
	}
}

public class C1 extends A1 {
	private int y;
	public C1(int y, int x) {
		super(x);
		this.y = y;
	}
	@Override
	public String toString() {
		return y + "<>" + x;
	}
}

public class D1 extends B1 {
	public D1(int x) {
		super(x + 1);
	}
	public int g() {
		return x - 2;
	}
	@Override
	public String toString() {
		return "{" + x + "}";
	}
}

public class E1 extends C1 {
	public E1(int y, int x) {
		super(y - 1, x + 1);
	}
	public int g(int z) {
		return x + z;
	}
}

Pour chaque ligne du programme suivant, indiquez l'affichage produit si la ligne compile (il peut ne pas y avoir d'affichage pour une ligne qui compile, ce qu'il faut indiquer), ou indiquez que la ligne ne compile pas.

A1 a = new A1(4);
System.out.println(a + " " + a.f());
B1 b = new B1(5);
System.out.println(b + " " + b.f());
Object o = b;
System.out.println(o);
C1 c = new C1(1, 2);
System.out.println(c + " " + c.f());
a = c;
System.out.println(a + " " + a.f());
D1 d = new D1(3);
System.out.println(d + " " + d.f() + " " + d.g());
b = d;
System.out.println(b + " " + b.f());
E1 e = new E1(0, 3);
System.out.println(e + " " + e.f() + " " + e.g(3));
a = e;
System.out.println(a + " " + a.f() + " " + a.g());
b = e;
System.out.println(b + " " + b.f() + " " + b.g(3));

Les trois dernières lignes du programme ne compilent pas. Le reste du programme affiche :

[4] 5
[5] 7
[5]
1<>2 3
1<>2 3
{4} 6 2
{4} 6
-1<>4 5 7