Exercices sur les structures de contrôle, les structures de données, les structures itératives #
Questions/Réponses #
Veuillez répondre mentalement, sur papier ou bien en créant le code nécessaire pour répondre à ces questions avant de regarder la réponse.
Quand on vous demande de produire du code, vous devez le tester. C'est une erreur commune chez les étudiants: ils produisent rapidement du code en supposant qu'il est fonctionnel. Prenez le temps de vous relire, d'être attentif. Et testez votre code. Encore et encore.
Prenez note qu'il est permis d'utiliser le robot conversationnel du cours lors des exercises. Cependant vous devriez vous entraîner à produire vos propres réponses.
Réponses uniques? #
Les exercices comportent une solution vous permettant de comparer votre approche avec la nôtre. Il n'y a pas de solution unique aux problèmes en général. Vous pouvez arriver avec une solution qui est préférable ou moins bonne que celle que nous offrons. Pour faire ces questions, vous devez avoir fait toutes les lectures préalables. Vous disposez alors toujours des fondements nécessaires pour faire les exercices. Nous vous encourageons tout de même à faire vos propres recherches en complément de vos lectures. Dans certains cas, au sein de la solution que nous offrons, nous pouvons utiliser des notions techniques qui n'ont pas été vues directement dans le cours, mais qui devraient vous être facilement accessibles.
Question 1 #
Si x == true et que l'on utilise le code suivant, quel sera la sortie en ligne de commande?
if(x != true && x == true) {
System.out.println("AAA");
} else {
System.out.println("BBB");
}
Réponse
Le résultat affiché sera BBB, car x != true donnera Faux et x == true donnera Vrai. Par définition, Faux ET Vrai = FAUX
Question 2 #
Le code suivant contient 5 erreurs, veuillez les identifier :
int x = 5;
if((x > 1) && (x =< 10) {
x = "5";
} if (x !!= 5) {
x = 100;
}
Réponse
Voici les erreurs :
- l'opérateur =< n'existe pas, c'est plutôt <=
- il manque une parenthèse ")" à la première ligne if (avant le })
- on ne peut assigner une String à un int
- en supposant que l'indentation est correcte, il manque le else pour } else if (
- l'opérateur !!= n'existe pas, c'est plutôt !=
int x = 5;
if((x > 1) && (x <= 10)) {
x = 5;
} else if (x != 5) {
x = 100;
}
Question 3 #
Quelle est la différence entre une boucle while et une boucle do-while?
Réponse
Le contrôle se fait au départ dans la boucle while alors que le contrôle se fait à la fin dans le do-while. Dans la boucle while, il y a donc un contrôle avant même de faire la première itération.
Question 4 #
Quelle sera la sortie d'affichage de ce block switch-case et pourquoi?
int index = 10;
switch (index) {
case 1:
System.out.println(11);
break;
case 2:
System.out.println(22);
break;
case 3:
System.out.println(33);
break;
default:
System.out.println("Default");
break;
}
Réponse
La sortie sera "Default", car la valeur de la variable index = 10 ne correspond à aucun des cas du switch. C'est donc le sous-bloc "Default" qui est exécuté.
Question 5 #
Vrai ou faux: un tableau de type int[10] occupera 40 octets en mémoire parce qu'il y a 10 entiers (int) et que chaque entier occupe 4 octets (32 bits).
Réponse
Faux. Il est vrai qu'il y a 10 entiers (int) et que chaque entier occupe 4 octets. Cependant, Java doit aussi garder une trace de la longueur du tableau (10 éléments). Il y a aussi d'autres contraintes. Il serait plus juste de dire que le tableau va utiliser plus de 40 octets.
Question 6 #
Supposons que dans un code, nous avons créé un tableau d'une dimension de 10 éléments (int[] tableau = new int[10]) et que nous accédons, suite à son instanciation, au 20e élément du tableau ( int x = tableau[20]), qu'adviendra-t-il?
Réponse
À l'exécution l'opération int x = tableau[20] va générer une erreur du type : java.lang.ArrayIndexOutOfBoundsException: 20, car nous tentons d'accéder à des index du tableau qui n'existe pas.
Question 7 #
Est-ce possible de créer une structure de données de type ArrayList d'entier en utilisant la déclaration suivante : ArrayList
Réponse
Le Java est un langage OO et même si le Java intègre des types de base (int, float, etc.) qui ne sont pas des objets. L'objet ArrayList ne peut que contenir des objets. Il faut donc utiliser plutôt : ArrayList
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(5);
Question 8 #
Votre employeur vous demande créer une fonction en Java qui vous permettra de trouver dans un tableau à deux dimensions, un couple {clé,valeur}. Pour démarrer, vous avez le code suivant, veuillez créer une fonction trouver qui reçoit en paramètre la clé et retourne la valeur :
public class Dictionnaire {
int[][] tableau2D = {{5,3},{2,5},{4,3},{8,10},{105,32},{55,34},{12,21},
{15,51},{44,1},{6,3},{19,3},{65,13},{1235,1353},{51515,32143},
{15155,3555}};
public static void main(String[] args) {
Dictionnaire dict = new Dictionnaire();
//Trouver la valeur associée à la clé
//System.out.println("Valeur =" + dict.trouver(12));
}
}
Réponse
Voici le code
public class Dictionnaire {
int[][] tableau2D = {{5,3},{2,5},{4,3},{8,10},{105,32},{55,34},{12,21},
{15,51},{4,1},{6,3},{19,3},{65,13},{1235,1353},{51515,32143},
{15155,3555}};
/**
* Fonction permettant de trouver une valeur à partir d'une clé
* @param clef
* @return valeur
*/
int trouver(int clef) {
// Initialiation de la variable valeur. Si la clef n'est pas trouvé alors on retourne -1.
int valeur = -1;
// Itération dans le tableau pour trouver le bon
for(int i = 0; i < tableau2D.length; i++) {
// Vérification de la cle avec l'index courant;
if (tableau2D[i][0] == clef) {
// Si oui, arrêter l'exécution et retourner la valeur.
return tableau2D[i][1];
// ou valeur = tableau2D[i][1]; break;
}
}
return valeur;
}
public static void main(String[] args) {
Dictionnaire dict = new Dictionnaire();
//Trouver la valeur associée à la clé
System.out.println("Valeur =" + dict.trouver(12));
}
}
Question 9 #
Montrer comment on peut trier un tableau d'entiers en Java.
Réponse
Le plus simple est d'utiliser la méthode Arrays.sort.
import java.util.Arrays;
class Main {
public static void main(String[] args) {
int[] tableauTest = {4, 6, 9, 1, 2, 76, 222, 5, 22};
Arrays.sort(tableauTest);
for (int i : tableauTest) {
System.out.print(i + " ");
}
System.out.println();
}
}
Question 10 #
Veuillez créer une fonction, recevant un ArrayList en entrée, et qui retourne une nouvelle ArrayList avec les éléments inversés, i.e. le premier élément à la fin, le dernier élément en premier et ainsi de suite.
Réponse
Voici une solution possible. Elle est grossièrement inefficace sur le plus du temps de calcul: vous pouvez sans doute faire mieux.
import java.util.ArrayList;
public class ArrayListUtils {
public static ArrayList inverser(ArrayList liste) {
ArrayList inverse = new ArrayList();
for(Object o : liste) {
inverse.add(0, o);
}
return inverse;
}
public static void main(String[] args) {
ArrayList<String> test = new ArrayList<String>();
test.add("1");
test.add("2");
test.add("3");
test.add("4");
test.add("5");
ArrayList<String> testInverse = ArrayListUtils.inverser(test);
for(String s : testInverse) {
System.out.print(s + " ");
}
}
}
Voici une autre solution (n'oubliez pas 'import java.util.Collections').
ArrayList<String> test = new ArrayList<String>();
test.add("1");
test.add("2");
test.add("3");
test.add("4");
test.add("5");
Collections.reverse(test);
for(String s : test) {
System.out.print(s + " ");
}
Question 11 #
Vous devez créer une méthode supplémentaire au code de la Question #10, permettant de fusionner deux ArrayList ensemble. Cette méthode prend deux ArrayLists en paramètre et retourne le nouvel ArrayList fusionné.
Réponse
La méthode addAll de la classe ArrayList permet de rapidement faire cette fusion :
import java.util.ArrayList;
public class ArrayListUtils {
public static ArrayList inverser(ArrayList liste) {
ArrayList inverse = new ArrayList();
for(Object o : liste) {
inverse.add(0, o);
}
return inverse;
}
public static ArrayList fusion(ArrayList a, ArrayList b) {
// Permet de cloner la structure. Nécessite un cast
ArrayList liste = (ArrayList) a.clone();
// Ajouter l'ArrayList b à la fin de liste
liste.addAll(b);
return liste;
}
public static void main(String[] args) {
ArrayList<String> test = new ArrayList<String>();
test.add("1");
test.add("2");
test.add("3");
test.add("4");
test.add("5");
ArrayList<String> listFusion = ArrayListUtils.fusion(test, test);
for(String s : listFusion) {
System.out.print(s + " ");
}
}
}
Question 12 #
Veuillez écrire le code (classe et méthode(s)) permettant de faire afficher le texte suivant à la console. Vous ne pouvez utiliser qu'une seule fois la méthode System.out.println.
###?###?###?###?###?###?###?###
???#???#???#???#???#???#???#???
??###?###?###?###?###?###?###??
?????#???#???#???#???#???#?????
????###?###?###?###?###?###????
???????#???#???#???#???#???????
??????###?###?###?###?###??????
?????????#???#???#???#?????????
????????###?###?###?###????????
???????????#???#???#???#???????
??????????###?###?###??????????
?????????????#???#?????????????
????????????###?###????????????
???????????????#???????????????
??????????????###??????????????
Réponse
import java.util.ArrayList;
// solution par Francis Beauchemin-Côté
public class Main {
public static String trioMotif(String caractere1, String caractere2, int nombreCaractere1) {
String motif = "";
for (int i = 1; i <= nombreCaractere1; i++) { // On veut mettre le nombre de trio demandé.
motif += caractere1 + caractere1 + caractere1; // Le premier argument est un String pour ne pas faire la somme en
// int (si un char avait été utilisé). Donc + est une
// concaténation.
if (i != nombreCaractere1) { // On n’ajoute pas de motif de séparation après le dernier trio.
motif += caractere2; // Comme motif est un String, la somme avec un char devient en fait une
// concaténation. On utilise ici un String dans le but d'uniformiser et
// simplifier l'utilisation.
}
}
return motif;
}
public static String nbInter(String carac, int nombreInterrogation) { // Crée le String entourant
// les motifs de trio.
String chaine = "";
for (int i = 1; i <= nombreInterrogation; i++) {
chaine += carac;
}
return chaine;
}
public static void pyramide(String premierChar, String deuxiemeChar, int nombreDeLignes) {
ArrayList < String > texte = new ArrayList < String > (); // Notre texte sera un vecteur de String.
for (int i = 0; i < (nombreDeLignes + 1) / 2; i++) { // Comme c'est une division entière, la division ne prend que
// le quotient entier.
texte.add(nbInter(deuxiemeChar, 2 * i) + trioMotif(premierChar, deuxiemeChar, (nombreDeLignes + 1) / 2 - i) + nbInter(deuxiemeChar, 2 * i));
texte.add(nbInter(deuxiemeChar, 2 * i) + trioMotif(deuxiemeChar, premierChar, (nombreDeLignes + 1) / 2 - i) + nbInter(deuxiemeChar, 2 * i));
} // On imprime deux lignes à la fois! On ajuste le nombreDeLignes par + 1. Il y a
// un nombre pair de motifs qui entourent les motifs avec les trios
if (nombreDeLignes % 2 == 1) { // Comme on imprime un nombre pair de lignes, il faut retirer
// la dernière dans le cas où le nombre de lignes est impair.
texte.remove(nombreDeLignes); // Le rang du n+1 ième élément est n.
}
for (String e: texte) { // Affiche le texte à l'écran ligne par ligne.
System.out.println(e);
}
}
public static void main(String[] args) {
pyramide("#", "?", 100);
}
}
Question 13 #
Écrivez un programme efficace Java qui prend la chaîne de caractère « 124213 » et en extrait les nombres 1, 2, 4, 2, 1, 3.
Réponse
class Exemple {
public static int[] extrait(String s) {
int[] answer = new int[s.length()];
for(int index = 0; index < s.length(); index++) {
answer[index] = Character.digit(s.charAt(index), 10);
}
return answer;
}
public static void main(String[] args) {
for(int x: extrait("124213")) {
System.out.println(x);
}
}
}
Question 14 #
Qu’est-ce qui s’affiche à l’exécution du bout de code suivant :
public class Main {
public static void main(String args[]) {
if (true)
if (false)
if (true)
System.out.println("avant le premier else");
else
System.out.println("après le premier else");
if (true)
System.out.println("avant le second else");
else
System.out.println("après le second else");
}
}
Expliquer pourquoi.
Réponse
Le code affiche « avant le second else ».
En effet le second if est évalué à false, et toute l’instruction qui suit (y compris l’évaluation du else qui se rapporte au if de cette instruction) n’est pas exécutée ; l’instruction suivante c’est le tout dernier if, qui est évalué à true, et donc le else qui s’y rapporte n’est pas évalué.
Question 15 #
Soit les deux bouts de code suivants :
a)
for (int j=0; j < 10; j++) {
if (j>=5) {
continue;
}
Instruction
}
b)
for (int j=0; j < 10;j++) {
if (j>=5) {
break;
}
Instruction
}
Que se passe-t-il dans chacun des cas quant à l’exécution de Instruction quand j vaut 5?
Réponse
En a) Instruction n’est pas exécutée et on passe au tour suivant, le 7eme tour de la boucle (i=6) où, comme lors des autres tours précédant i=5, Instruction sera exécutée.
En b) on sort de la boucle, Instruction ne sera plus jamais exécutée.
Question 16 #
Soit les deux bouts de code suivants :
a)
label:
for (int i=0; i < 10;i++) {
for (int j=0; j < 6; j++) {
if (condition) {
continue label;
}
Instruction1
}
Instruction2
}
b)
for (int i=0; i < 10; i++) {
for(int j=0; j < 6; j++) {
if(condition) {
continue ;
}
Instruction1
}
Instruction2
}
Dans quel cas (quel bout de code et quelle condition) Instruction1 n'est pas exécuté? Y'a-t-il une situation où Instruction2 n'est pas exécuté? Si oui laquelle?
Réponse
Instruction1 n’est pas exécuté, dans tous les cas lorsque condition est vraie.
Instruction2 est toujours exécuté.
Question 17 #
Soit le code suivant :
public class Main {
public static void main(String[] args) {
final int NBRE = 10;
int i;
double harmonique;
harmonique = 0;
System.out.println("somme des " + NBRE + " premiers termes de la série harmonique");
for (i = 0; i < NBRE; i++) {
harmonique += (double)1/(i+1);
}
System.out.println("Somme : " + harmonique);
}
}
Réécrire le même code en utilisant les syntaxes de l’instruction while et de l’instruction do…while.
Réponse
Instruction while.
public class Main {
public static void main(String[] args) {
final int NBRE = 10;
int i=0;
double harmonique;
harmonique = 0;
System.out.println("somme des " + NBRE + " premiers termes de la série harmonique");
while (i < NBRE) {
harmonique += (double)1/(i+1);
i++;
}
System.out.println("Somme : " + harmonique);
}
}
Instruction do…while
public class Main {
public static void main(String[] args) {
final int NBRE = 10;
int i = 0;
double harmonique;
harmonique = 0;
System.out.println("somme des " + NBRE + " premiers termes de la série harmonique");
do {
harmonique += (double)1/(i+1);
i++;
} while (i < NBRE);
System.out.println("Somme : " + harmonique);
}
}
Question 18 #
Soit le code suivant :
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
System.out.println("Donnez un nombre entier");
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
if (n>=10) {
System.out.println("Le nombre vaut 10");
} else if (n >= 100) {
System.out.println("Le nombre vaut 100");
} else if (n >= 1000) {
System.out.println("Le nombre vaut 1000");
} else {
System.out.println("Le nombre n'est pas une puissance de 10 ou il est plus grand que 1000");
}
}
}
Réécrire le même programme avec l'instruction switch.
Réponse
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
System.out.println("Donnez un nombre entier");
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
switch(n)
{
case 10 :
System.out.println("Le nombre vaut 10");
break;
case 100 :
System.out.println("Le nombre vaut 100");
break;
case 1000 :
System.out.println("Le nombre vaut 1000");
break;
default:
System.out.println("Le nombre n'est pas une puissance de 10 ou il est plus grand que 1000");
break;
}
}
}
Question 19 #
Étant donné le tableau String[] x = new String[10], que vaut x[0].
Réponse
En Java, les tableaux sont initialisées à une valeur nulle par défaut. Dans ce cas, x[0] prendra donc la valeur null. Cette valeur spéciale ne correspond pas à une instance de la classe String. On peut, par contre, assigner une valeur (x[0]="123").
Question 20 #
Énumérer toutes les paires d'entiers entre 0 et 1000 en ordre lexicographique.
Réponse
public class Liste {
public static void main(String[] args) {
for(int i = 0; i <= 1000; i++) {
for(int j = 0; j <= 1000; j++) {
System.out.println(i+" "+j);
}
}
}
}
Question 21 #
Écrivez un programme Java qui trie le tableau de chaînes de caractères suivant : {"Pomme", "banane", "Cerise", "abricot", "Datte"}, en ignorant la casse (par exemple, "Pomme" et "pomme" doivent être traités de manière identique). Utilisez la méthode Arrays.sort avec une expression lambda pour effectuer un tri alphabétique insensible à la casse.
Une expression lambda est une fonctionnalité introduite dans Java 8 qui permet d'écrire du code plus concis pour représenter des fonctions anonymes. Elle est particulièrement utile lorsqu'une méthode attend une interface fonctionnelle (une interface avec une seule méthode abstraite). Dans le contexte du tri avec Arrays.sort, la lambda remplace une implémentation explicite d'un Comparator.Une lambda a la forme générale suivante : (paramètres) -> expression La lambda (s1, s2) -> s1.compareToIgnoreCase(s2) signifie : s1 et s2 sont deux chaînes de caractères à comparer, la méthode compareToIgnoreCase est appelée pour déterminer l'ordre alphabétique sans tenir compte de la casse, le résultat de cette comparaison est retourné directement.
Réponse
Question 22 #
Écrivez un programme Java qui affiche la somme des éléments d’un tableau d’entiers donné.
Réponse
int[] t = {1, 2, 3, 4, 5};
int somme = 0;
for (int v : t) {
somme += v;
}
System.out.println("Somme : " + somme);
Question 23 #
Expliquez la différence entre une boucle for et une boucle while en Java, et donnez un exemple pour chacune.
Réponse
La boucle for est généralement utilisée quand on connaît le nombre d’itérations à l’avance ; la boucle while est utilisée quand on ne le connaît pas.
// Boucle for
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
// Boucle while
int j = 0;
while (j < 5) {
System.out.println(j);
j++;
}
Question 24 #
Quelle est la différence entre un tableau et une ArrayList en Java ?
Réponse
Un tableau a une taille fixe et ne peut pas être redimensionné après sa création. Une ArrayList est une structure de données dynamique qui peut changer de taille et offre des méthodes pratiques pour ajouter, supprimer ou rechercher des éléments.
Question 25 #
Écrivez un programme Java qui affiche tous les éléments d’un tableau d’entiers dans l’ordre inverse.
Réponse
int[] t = {1, 2, 3, 4, 5};
for (int i = t.length - 1; i >= 0; i--) {
System.out.println(t[i]);
}
Question 26 #
Qu'est-ce qu'une HashMap
en Java ? Donnez un exemple simple d'utilisation pour associer des noms d'étudiants à leurs notes.
Réponse
Une HashMap
est une structure de données qui associe des clés à des valeurs. Elle permet de retrouver rapidement une valeur à partir de sa clé. Exemple :
import java.util.HashMap;
HashMap<String, Integer> notes = new HashMap<>();
notes.put("Alice", 85);
notes.put("Bob", 92);
System.out.println(notes.get("Alice")); // Affiche 85
Question 27 #
Que se passe-t-il si on ajoute deux fois la même clé dans une HashMap
en Java ? Par exemple :
HashMap<String, Integer> map = new HashMap<>();
map.put("clé", 1);
map.put("clé", 2);
Quelle sera la valeur associée à la clé “clé”
?
Réponse
La deuxième insertion écrase la première : la valeur associée à la clé "clé"
sera 2. Une HashMap
ne peut contenir qu'une seule valeur par clé ; si on ajoute une clé déjà existante, la nouvelle valeur remplace l'ancienne.
Question 28 #
Comment utiliser une Stack
en Java pour inverser l'ordre des éléments d'une liste ? Donnez un exemple de code qui empile les éléments d'un tableau d'entiers, puis les dépile pour les afficher dans l'ordre inverse.
Réponse
On peut utiliser une Stack
pour inverser l'ordre des éléments : on empile chaque élément, puis on les dépile un à un (LIFO : Last In, First Out).
import java.util.Stack;
int[] t = {1, 2, 3, 4, 5};
Stack<Integer> pile = new Stack<>();
for (int x : t) {
pile.push(x);
}
while (!pile.isEmpty()) {
System.out.println(pile.pop());
}
Question 29 #
Qu’est-ce que l’interface CharSequence
en Java ? Donnez un exemple d’utilisation de la méthode subSequence()
sur une chaîne de caractères.
Réponse
L’interface CharSequence
représente une séquence de caractères et est implémentée par String
, StringBuilder
, etc. La méthode subSequence(start, end)
permet d’obtenir une sous-séquence de caractères.
Exemple :
String texte = "Bonjour le monde";
CharSequence sousTexte = texte.subSequence(8, 14); // "le mon"
System.out.println(sousTexte);
On peut ainsi éviter de faire des copies.
Question 30 #
Pourquoi est-il préférable d’utiliser StringBuilder
plutôt que l’opérateur +
pour concaténer des chaînes dans une boucle ? Donnez un exemple.
Réponse
StringBuilder
permet de modifier une chaîne sans créer de nouveaux objets à chaque opération, ce qui améliore la performance, surtout dans les boucles. L’opérateur +
de la classe String peut créer une nouvelle chaîne à chaque concaténation, ce qui est coûteux en mémoire et en temps.
Exemple :
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 5; i++) {
sb.append("Ligne ").append(i).append("\n");
}
System.out.println(sb.toString());
Question 31 #
Quels sont les types et classes immuables en Java ? Donnez quelques exemples et expliquez pourquoi l’immuabilité peut être utile.
Réponse
Un type ou une classe est dit immuable si son état ne peut pas être modifié après sa création. En Java, les principaux types et classes immuables sont :
String
- Les classes enveloppes des types primitifs :
Integer
,Double
,Boolean
,Long
,Short
,Byte
,Character
,Float
L’immuabilité facilite la programmation (pas de risque de modification imprévue), rend les objets sûrs à partager, et simplifie le raisonnement sur le code.
Question 32 #
Considérez le code suivant :
public class Main {
public static void main(String[] args) {
String str1 = "Java";
String str2 = "Java";
String str3 = new String("Java");
System.out.println(str1 == str2);
System.out.println(str1 == str3);
}
}
Qu’affichera ce programme ? Expliquez pourquoi.
Réponse
Le premier affichage (str1 == str2
) retournera true car les deux variables pointent vers la même chaîne littérale dans le pool de chaînes de Java. Le second (str1 == str3
) retournera false car str3
est un nouvel objet créé explicitement, différent de la chaîne littérale, même si leur contenu est identique. Pour comparer le contenu des chaînes, il faut utiliser equals()
:
System.out.println(str1.equals(str3)); // true
En Java, les chaînes de caractères sont des objets particuliers : les chaînes littérales (comme “Java”) sont stockées dans une zone spéciale appelée « pool de chaînes ». Quand on écrit deux fois la même chaîne littérale dans le code, Java réutilise le même objet pour économiser de la mémoire. C’est pourquoi str1 == str2
retourne true : les deux variables pointent vers le même objet en mémoire.
En revanche, lorsque l’on crée une chaîne avec new String(“Java”)
, Java crée explicitement un nouvel objet, même si le contenu est identique à une chaîne littérale existante. Ainsi, str1 == str3
retourne false car les deux variables pointent vers des objets différents.
Pour comparer le contenu de deux chaînes (et non leur emplacement en mémoire), il faut utiliser la méthode equals()
. Cette méthode vérifie caractère par caractère si les deux chaînes ont le même contenu, ce qui est généralement ce que l’on souhaite en pratique.
Question 33 #
Nous savons que la somme 1/2 + 1/4 + 1/8 +... donne la valeur unitaire.
Sachant qu'un type double en Java a une mantisse comportant 53 bits, que va afficher le programme suivant?
class Main {
public static void main(String[] args) {
double x = 0;
double f = 1.0;
for (int i = 0; i < 53; i++) {
f /= 2;
x += f;
}
System.out.println(x==1.0);
f /= 2;
x += f;
System.out.println(x==1.0);
}
}
Réponse
false, true
Question 34 (pour les experts !) #
Considérons la décroissance radioactive d’un isotope. Supposons que nous ayons une quantité initiale de matière radioactive, et nous voulons modéliser comment sa masse diminue avec le temps en raison de la désintégration. Ce phénomène est courant en physique nucléaire, en médecine (pour les traitements par radiothérapie) et en datation au carbone.
La décroissance radioactive suit une loi où la vitesse de diminution de la masse \( N \) (nombre de particules ou masse restante) est proportionnelle à la masse actuelle. Mathématiquement, cela s’exprime comme :
\[ \frac{dN}{dt} = -\lambda N \]- \( N(t) \) : masse (ou nombre de particules) restante à l’instant \( t \).
- \( \lambda \) : constante de désintégration (spécifique à l’isotope, en \( \text{s}^{-1} \)).
- Le signe négatif indique que la masse diminue.
Cette équation différentielle décrit un taux de changement proportionnel à la quantité présente. Par exemple, pour le carbone-14, \( \lambda \approx 3.839 \times 10^{-12} \, \text{s}^{-1} \), mais pour simplifier, nous utiliserons une constante plus grande, comme \( \lambda = 0.1 \, \text{s}^{-1} \), pour observer une décroissance significative sur un intervalle court.
- Condition initiale : À \( t = 0 \), la masse initiale est \( N_0 = 100 \, \text{g} \).
- Intervalle : Nous modélisons sur \( t \) de 0 à 20 secondes.
- Méthode : Nous utiliserons la méthode d’Euler pour résoudre numériquement cette équation. La méthode d’Euler est une technique numérique simple pour résoudre des équations différentielles ordinaires en approximant la solution par des pas discrets. Elle repose sur l’idée que la dérivée d’une fonction donne la pente locale, permettant d’estimer la valeur suivante à partir de la valeur actuelle et d’un pas de temps \( h \). Pour une équations différentielles ordinaires de la forme \( \frac{dy}{dt} = f(t, y) \), la méthode calcule \( y_{n+1} = y_n + h \cdot f(t_n, y_n) \).
Voici le pseudocode de la méthode d’Euler.
Entrée :
- fonction \( f(x, y) \) (dérivée)
- \( x_0 \), \( y_0 \) (conditions initiales)
- \( x_f \) (valeur finale de \( x \))
- \( h \) (taille du pas)
Sortie :
- liste des points \((x_i, y_i)\) approximant la solution
- Initialiser \( x = x_0 \), \( y = y_0 \)
- Initialiser une liste vide pour stocker les points \((x_i, y_i)\)
- Ajouter le point \((x, y)\) à la liste
- Tant que \( x < x_f \):
- Calculer la pente : \( m = f(x, y) \)
- Mettre à jour \( y \): \( y = y + h \cdot m \)
- Mettre à jour \( x \): \( x = x + h \)
- Ajouter le nouveau point \((x, y)\) à la liste
- Retourner la liste des points
Écrivez un programme qui utilise la méthode d’Euler pour résoudre l’équation \( \frac{dN}{dt} = -0.1 N \), avec \( N(0) = 100 \), et affiche la masse restante à chaque pas de temps.
Réponse
Question 35 (pour les experts !) #
Décrivez le fonctionnement de l’algorithme de tri par insertion. Implémentez cet algorithme en Java pour trier un tableau d’entiers en ordre croissant. Votre programme doit afficher le tableau avant et après le tri.
Réponse
L’algorithme de tri par insertion parcourt un tableau élément par élément, en insérant chaque élément à sa position correcte dans la partie déjà triée. Pour chaque élément, il le compare avec les éléments précédents et le déplace vers la gauche jusqu’à ce qu’il soit à sa place.Le programme Java ci-dessus implémente le tri par insertion. La méthode insertionSort
prend un tableau d’entiers, utilise une boucle pour parcourir les éléments, et insère chaque élément à la bonne position en décalant les éléments plus grands. Le programme affiche le tableau avant et après le tri.
Question 36 (pour les experts !) #
Décrivez le fonctionnement de l’algorithme de tri à bulle. Implémentez cet algorithme en Java pour trier un tableau d’entiers en ordre croissant. Votre programme doit afficher le tableau avant et après le tri.
Réponse
Le tri à bulle parcourt répétitivement un tableau, comparant des éléments adjacents et les échangeant s’ils sont dans le mauvais ordre. À chaque itération, l’élément le plus grand de la portion non triée est placé à la fin, comme une bulle qui remonte.Le programme Java ci-dessus implémente le tri à bulle. La méthode bubbleSort
utilise deux boucles imbriquées pour comparer et échanger les éléments adjacents. Le programme affiche le tableau avant et après le tri.
Question 37 (pour les experts !) #
Décrivez le principe de la recherche binaire dans un tableau trié. Implémentez cet algorithme en Java pour trouver l’indice d’un élément dans un tableau d’entiers trié en ordre croissant. Votre programme doit retourner l’indice de l’élément s’il est trouvé, ou -1 sinon, et afficher un message indiquant le résultat.
Réponse
La recherche binaire trouve un élément dans un tableau trié en divisant itérativement l’intervalle de recherche par deux. Elle compare l’élément cible avec l’élément central, puis restreint la recherche à la moitié inférieure ou supérieure selon le résultat. Le tableau doit être trié au préalable.Le programme Java implémente la recherche binaire. La méthode binarySearch
prend un tableau trié et un élément cible, utilise une boucle pour ajuster les indices debut
et fin
, et retourne l’indice de l’élément ou -1 s’il n’est pas trouvé. Le programme affiche un message indiquant le résultat.