Master 2 CCI 2012-2013 |
POO,
langage Java
|
Henri
Garreta
|
Le signe © renvoie à la correction |
Saisissez, compilez et exécutez un programme Java qui affiche Bonjour à tous ! sur lécran de la console. Pour cela, écrivez une classe publique exécutable nommée Bonjour placée dans un fichier nommé Bonjour.java. Trois « détails » à ne pas oublier :
Observez ce qui se passe lorsque vous désobéissez à une des trois prescriptions précédentes.
Afin de constater lexistence dans la bibliothèque Java dun générateur de nombres pseudo-aléatoires, écrivez un programme qui obtient n nombres « au hasard » (par exemple, n = 100 000) et qui calcule la moyenne et lécart-type de la suite ainsi déterminée.
Pour produire des nombres pseudo-aléatoires utilisez la méthode java.lang.Math.random() (cela se lit : « la méthode random()
de la classe Math
du paquetage java.lang
»), sur laquelle vous trouverez des indications dans la documentation de lAPI. Essentellement, il faut savoir que chaque fois quon lappelle, cette méthode renvoie un nombre flottant de lintervalle [0 ; 1[ (0 est compris, 1 exclu).
Un des buts de cet exercice est justement de vous initier à la consultation de la documentation Java. Pour cela, ouvrez un navigateur sur la « doc de lAPI » (soit chez Sun, http://java.sun.com/javase/6/docs/api/, soit plus près de nous www.dil.univ-mrs.fr/~garreta/docJava/api/) ; dans le volet supérieur gauche sélectionnez le paquetage
java.lang
et, alors, dans le volet inférieur gauche sélectionnez la classeMath
. Parmi les méthodes de cette classe, cherchezrandom
et lisez-en la documentation.
Notes. Vous pouvez aussi employer des méthodes de la classe java.util.Random
, qui est entièrement consacrée à la génération de suites pseudo-aléatoires ; cependant, pour ce que nous avons à faire ici, la méthode java.lang.Math.random() suffit amplement. Bien entendu, si vous utilisez la classe java.util.Random
, évitez de nommer Random
votre propre classe !
Rappel des formules. Si n est le nombre de termes dune suite, S = x1 + x2 + ... + xn la somme de ces termes et Q = x12 + x22 + ... + xn2 la somme de leurs carrés, alors
N.B. Les statisticiens nous apprennent que, si la distribution des valeurs renvoyées par la fonction random est uniforme, quand n devient de plus en plus grand m tend vers 0,5 et s vers 0,288675134595 (la racine carrée de 1/12).
Écrivez une méthode statique qui reçoit deux tableaux triés de nombres entiers et qui construit et renvoie un troisième tableau, également trié, constitué par la fusion des deux tableaux donnés. Les doublons seront éliminés ; cependant, le tableau résultat sera « plein » (c’est-à-dire ayant exactement le nombre d’éléments nécessaire).
Pour essayer cette méthode, écrivez un programme (méthode main) qui initialise deux tableaux avec des constantes, les affiche et affiche également le résultat de leur fusion.
Le but de cet exercice est de vous initier à lutilisation de la classe java.util.Scanner
, qui permet deffectuer simplement des
lectures à la console, comme on le fait en C avec la fonction scanf
.
Cette classe est disponible à partir de la version 5 de Java.
Cela semploie de la manière suivante : au début du programme,
on crée une instance (nommée ici entree
)
connectée à un flot en entrée, qui très souvent est lentrée
standard System.in
:
Scanner entree = new Scanner(System.in);
ensuite, pour lire un entier i
il suffit décrire
i = entree.nextInt();
pour lire un flottant x
:
x = entree.nextFloat();
Pour lire une chaîne s
s = entree.nextLine();
La chaîne renvoyée comme résultat par nextLine
sera
formée de tous les caractères quon va trouver sur System.in
à partir de maintenant et jusquau prochain caractère de
fin-de-ligne (on produit un caractère fin-de-ligne
au clavier en pressant la touche « Entrée »). Le
caractère fin-de-ligne lui-même sera lu, mais napparaîtra
pas dans la chaîne résultat.
Exercice. Pour essayer la classe Scanner
, écrivez
en Java le programme qui calcule et affiche la moyenne dune suite de nombres
décimaux positifs ou nuls, lus au clavier, dont la fin est indiquée par un nombre négatif.
Exemple dexécution (ce qui a été tapé par
lutilisateur est souligné) :
Donner les nombres (terminer par -1): 14 8,5 10 12 5,5 -1 moyenne: 10,0
N.B. 1 - La classe Scanner
prend en compte les particularités locales, cest pourquoi il faut écrire les nombres décimaux avec une virgule à la place du point, comme ci-dessus. Cest également le cas de la méthode printf
(employée ci-dessus pour obtenir laffichage de la moyenne), mais non des méthodes plus rustiques print
et println
.
N.B. 2 - Dans la lecture dun nombre, les éventuels caractères blancs (espaces, tabulations et fins-de-ligne) précédant le nombre sont toujours « avalés » et nont aucun effet. Cependant, les blancs suivant le nombre ne sont pas consommés ; il en est ainsi notamment de la fin-de-ligne souvent tapée pour finir le nombre, qui reste donc disponible pour les prochaines lectures. Cela se passe comme ça dans beaucoup de langages et cest la cause dun certain nombre de dysfonctionnements lorsquune lecture de nombre est suivie dune lecture de chaîne (à méditer).
Le but de cet exercice est de vous faire essayer diverses manières dobtenir et afficher la date courante et, surtout, un prétexte pour vous faire compulser la documentation...
A. Première manière : la méthode java.lang.System.currentTimeMillis() donne la date courante, exprimée comme le nombre de millisecondes qui se sont écoulées depuis le 1er janvier 1970 à 0 heures GMT. Cest précis, mais pas très pratique pour organiser sa semaine ! (Retenez quand même lexistence de cette méthode, car elle est bien utile pour mesurer les performances des programmes).
Écrivez un programme qui affiche le nombre s de secondes écoulées depuis le 1er janvier 1970. Exécutez deux fois ce programme, à une minute dintervalle, et voyez si l'écart des valeurs obtenues illustre lexplication donnée. Constatez que le nombre d'années exprimées par la valeur s est vraisemblable.
B. Deuxième manière : ajoutez au programme précédent des instructions qui créent un objet de type java.util.Date (par une expression comme « Date d = new Date(); ») et le donnent à afficher à System.out. Comme vous le voyez, cest mieux, car on obtient bien une date, mais écrite à la manière des anglo-saxons.
Ne cherchez pas la correction de ce défaut parmi les nombreuses méthodes de la classe Date, elles sont presque toutes deprecated (désapprouvées, c'est-à-dire en voie de péremption) et ne méritent pas quon sy investisse.
C. Troisième manière : créer un objet de type java.util.Calendar (par une expression comme « Calendar c = Calendar.getInstance(); ») et obtenir séparément les éléments de la date (le jour de la semaine, le jour du mois, le mois, lannée) pour les afficher comme bon nous semble.
En étudiant la documentation de la classe Calendar vous apprendrez quon obtient les divers composants par des expressions de la forme « c.get(Calendar.MONTH); », « c.get(Calendar.YEAR); », etc.
Des tableaux de chaînes déclarés comme ceci peuvent vous aider à produire une présentation soignée :
String[] mois = { "janvier", "février", ... "décembre" }; String[] jSem = { "lundi", "mardi", ... "dimanche" };
D. Quatrième manière (la plus « pro ») : construire un objet d de type java.util.Date comme dans la deuxième manière et un objet f de type java.text.SimpleDateFormat (qui est une variété de java.text.DateFormat) et afficher le résultat du formatage du premier par le second, par une expression comme f.format(d).
Ne vous laissez pas effrayer par la volumineuse documentation de SimpleDateFormat. Si vous ne voyez pas comment cela marche, essayez ceci et vous comprendrez :
... Date d = new Date(); SimpleDateFormat f = new SimpleDateFormat("dd MMMMM yyyy HH:mm"); System.out.println("maintenant: " + f.format(d)); ...
But de cet exercice : vous faire explorer la classe java.lang.String
en testant ses diverses méthodes sur des chaînes et dautres valeurs
lues au clavier. Il sagit d'écrire une classe exécutable TestChaines
dont la méthode principale effectue les opérations suivantes :
A. Lire un nombre et le convertir en chaîne (ex.: le nombre 12345 devient la chaîne "12345").
B. Lire une chaîne entièrement faîte de chiffres et la convertir dans le nombre entier quelle représente (ex.: la chaîne "12345" devient le nombre 12345). La solution se trouve parmi les méthodes statiques de la classe java.lang.Integer.
Si vous programmez ce test à la suite de celui de la question A vous constaterez que lorsque la lecture dune chaîne fait suite à celle dun nombre il est nécessaire de « nettoyer » lentrée en plaçant entre ces deux opérations la lecture à fonds perdu dune chaîne, destinée à consommer la marque de fin de ligne (trace de la touche « Entrée ») qui a probablement été tapée à la fin du nombre.
C. Même question que ci-dessus, mais avec un nombre flottant (ex.: la chaîne "0.12345e4" devient le nombre 0.12345e4).
D. Lire une chaîne représentant un nom de ville, lui enlever les éventuels blancs au début et à la fin et lafficher entièrement en majuscules.
E. Lire deux chaînes s1 et s2 et afficher la réponse à la question : « ces deux chaînes commencent-elles par le même caractère ? » Utilisez la méthode dinstance charAt.
F. Lire deux chaînes s1 et s2 et afficher les résultats renvoyés par les expressions « s1 == s2 », « s1.equals(s2) », « s1.compareTo(s2) » et , « s1.compareToIgnoreCase(s2) ». Entre autres, essayer les couples "abcd" et "abcd", puis "abcd" et "AbcD".
G. Lire deux chaînes s1 et s2 et afficher la réponse aux questions « s1 commence-t-elle par s2 ? », « s1 finit-elle par s2 ? » et « s1 contient-elle s2 ? »
H. Lire deux chaînes s1 et s2 et si s1 contient s2, renvoyer s1 privée de s2 (sintéresser à substring), sinon renvoyer s1.
I. Si s est une chaîne de caractères, lexpression
s.intern()
renvoie une chaîne ayant les mêmes
caractères que s mais appartenant à une collection de chaînes
sans doublons que Java maintient et dont les chaînes figurant dans
le programme source font partie doffice.
Lire deux chaînes s1
et s2
et
constater quà la suite des transformations « s1
= s1.intern();
» et « s2 = s2.intern();
»
les expressions « s1.equals(s2)
»
et « s1 == s2
» deviennent
équivalentes.
A. Écrivez une classe exécutable avec une méthode :
static long factorielle1(int n)
qui calcule la factorielle de n, cest-à-dire le nombre n! = n × (n 1) × (n 2) × ... × 3 × 2 × 1.
B. Trouvez la valeur de n à partir de laquelle les débordements des valeurs entières rendent cette méthode inutilisable.
N.B. Une manière de vérifier que la valeur de n! est juste, sachant que celle de (n 1)! lest, consiste à afficher le rapport n! / (n 1)!
C. Pour pallier ce problème de débordement, écrivez
une nouvelle fonction utilisant des objets java.math.BigInteger
:
static BigInteger factorielle2(int n)
et constatez que maintenant on peut aller pratiquement aussi loin quon veut.
D. Aurions-nous pu donner le même nom aux fonctions factorielle1 et factorielle2 ?
Dans sa forme générale, la commande qui déclenche l'exécution d'une application Java s'écrit
java
UneClassechaîne0
chaîne0 ... chaînek1
où chaîne0
chaîne0 ... chaînek1 sont des chaînes de caractères ne contenant pas de blancs séparées par des blancs (espaces, tabulations).
Ces chaînes sont accessibles depuis lintérieur de lapplication à
travers le tableau, généralement appelé args
,
qui est déclaré dans len-tête de la fonction main
.
Par exemple, si une application est lancée par la commande
java NomDeLaClasse Dupond "Jean Pierre" 2006 2+3=5
alors la fonction main
reçoit un argument qui est
un tableau formé des quatre chaînes de caractères
"Dupond"
, "Jean Pierre"
,
"2006"
et "2+3=5"
.
Notez que :
2+3=5
forme un seul
argument.Exercice. Écrivez une classe Calcul
quon
exécute avec trois arguments : deux nombres et un opérateur
entre les deux, et qui affiche le résultat de lopération
indiquée sur les nombres indiqués. Exemple dexécution (ce
qui est saisi par lutilisateur est bleu) :
java Calcul 1200 + 400 1200 + 400 = 1600