Sei sulla pagina 1di 7

Université Mohammed Premier Année universitaire 2012-2013

Faculté des Sciences Filière SMI


Département de Mathématiques Module : POO Java
et d’Informatique Semestre : S5
Responsable du cours : El Mostafa DAOUDI

Solution du TP: Série Numéro 4

Exercice 1 : Gérer une pile d'entiers


Il s'agit de définir une classe nommée « Pile » modélisant une pile d'entiers positifs. Tous les attributs de
cette classe sont privés. Cette classe possède au moins les trois méthodes suivantes:
 void empiler(int x). Cette méthode empile la valeur x reçue en paramètre.
 int depiler() throws ExceptionPileVide. Si la pile est vide, cette méthode lance une exception. Sinon,
elle dépile (supprime) le dernier élément de la pile et retourne sa valeur.
 boolean estVide(). Cette méthode retourne « true » si la pile est vide. Sinon elle retourne « false ».

Pour les tests, on défini une classe, nommée « TestPile » qui contiendra la méthode main(). Pour la pile, on
utilise un tableau d'entiers. Au départ, ce tableau aura une taille initiale. En cas de besoin, il faut agrandir ce
tableau : lorsqu'il est plein et que l'on veut encore empiler un entier; on pourra alors agrandir le tableau d'une
quantité déterminée (par exemple égale au double de la taille du tableau courant).
Solution
import java.io.*;
class PileVide extends Exception {
public PileVide() { }
}
class Pile {
private int laPile[]; // Le tableau (la pile) dans lequel on va empiler les entiers positif.
private int dernier=-1; // l’attribut « dernier » désigne la position du dernier élément de la pile.
public Pile(int n) { // créé le tableau « laPile » avec une taille initiale lu au clavier.
laPile=new int[n];
}
public void afficher() { /* affiche les éléments de la pile. Attention: les éléments de la pile
sont situés entre 0 et la valeur de l’attribut « dernier ». /*
for(int i=0;i<=dernier;i++)
System.out.print(laPile[i]+" ");
System.out.println();
}
public boolean estVide() {
if (dernier<0)
return true;
else
return false;
}
public void empiler(int x) { /* ajout d'un élément dans la pile. Puisque on travaille avec des
tableaux et non avec des listes chainées, alors on doit agrandir la
taille du tableau lorsqu'il est plein et que l'on veut encore empiler
un entier. On pourra, par exemple, doubler la taille du tableau */
SMI-S5 Solution TP-4 : POO-Java, 2012-2013 1
int l=laPile.length;
dernier++;
if (dernier <laPile.length-1){ // s'il reste encore des places dans le tableau
laPile[dernier]=x;
}
else { /* si non, on créé un nouveau tableau « tab », de taille égale au double du tableau
courant « laPile », ensuite on copie les éléments du tableau courant « laPile »
dans le nouveau tableau « tab ».
Enfin, on change la référence de « laPile » qui référencera « tab ». */
int[] tab= new int [2*l];
System.arraycopy(laPile, 0, tab, 0, l); //copie des éléments de « laPile » dans « tab »
laPile=tab;
laPile[dernier]=x; // ajout de l’élément à empiler.
}
}
public int depiler() throws PileVide {
if (this.estVide()) throw ( new PileVide() );
int x = laPile[dernier];
dernier--; /* supprimer le dernier élément de la pile. Donc, on doit changer la position
du dernier élément de la pile. */
return x;
}
}
public class TestPile {
public static void main(String[] args) {
InputStreamReader in = null;
BufferedReader tampon = null;
try {
in = new InputStreamReader(System.in);
tampon = new BufferedReader(in);
/* On saisi un entier pour taille initiale du tableau */
System.out.print("Entrez la taille initiale de la pile : ");
int n = Integer.parseInt(tampon.readLine()); // conversion de String en un entier
Pile p=new Pile(n); // création d'une instance de la classe Pile
while (true) { /* saisi des éléments à empiler. Remarque: On peut saisir un
nombre d'éléments supérieur à n. Dans ce cas agrandissement
automatique de la taille du tableau (voir méthode « empiler() »). */
System.out.print("Entrez un élément à empiler : ");
int x = Integer.parseInt(tampon.readLine());
if (x==-1) // on s’arrête lorsque l'élément saisi es égale à -1
break;
else
p.empiler(x);
}
p.afficher(); // faire un affichage pour la vérification

SMI-S5 Solution TP-4 : POO-Java, 2012-2013 2


while (true) { /* On dépile les éléments : on supprime les éléments un à un
à partir du dernier élément. */
System.out.print("Voulez vous supprimer un élément : ");
char c = (tampon.readLine()).charAt(0);
if ((c=='o')||(c=='O')){
int x=p.depiler();
System.out.println("l'élément supprimé est "+x);
System.out.println("Pour test: affichage de la pile ");
p.afficher();
}
else
break;
}
}
catch (PileVide e) {
System.out.println("la pile est vide :");
}
catch (NumberFormatException e){
System.out.println("Entrer un entier positif");
}
catch (IOException ioe) {
System.out.println("Erreur de lecture au clavier :");
}
finally {
try {
tampon.close();
in.close();
} catch (IOException exception1) {
System.out.println("Erreur de fermeture des flux :");
}
}
Exercice 2 :
Le but est d'écrire un programme qui, étant donnée une chaîne de caractères (une instance de la classe
String) calcule la chaîne inverse et ensuite indique s'il s'agit ou non d'un palindrome.
N.B. Si une chaine de caractères est identique à son inverse alors c’est palindrome. Exemple la chaine «laval
» est un palindrome.

On définira deux classes.


La première classe, nommée « Palindrome », a deux méthodes :
- Une méthode qui retourne un objet de type String contenant la chaîne inverse de la chaîne donnée en
paramètre.
- Une méthode qui indiquera si la chaîne est un palindrome ou non.
La seconde classe, nommée « EssaiPalindrome », contient la méthode main(). Pour les tests, on récupère une
chaîne sur la ligne de commande ensuite on calcule et on affiche son inverse avec un message qui indique si
la chaîne est un palindrome ou non.
Solution 1 :
class Palindrome {
public static String inverse(String s){
int l=s.length();
SMI-S5 Solution TP-4 : POO-Java, 2012-2013 3
char [] s1 = new char[l];
for (int i=0; i<l; i++) {
s1[l-1-i]= s.charAt(i);
}
return new String (s1);
}
public static boolean isPalindrome(String s){
String s1=inverse(s);
return s1.equals(s);
}
}
public class EssaiPalindrome{
public static void main(String[] args) {
try {
String s = args[0];
boolean b=Palindrome.isPalindrome(s);
System.out.println("L'inverse de la chaine: "+s+" est : "
+Palindrome.inverse(s));
System.out.println("La chaine: "+s+" est un palindrom :"+b);
} catch (ArrayIndexOutOfBoundsException exc) {
System.out.println("Nombre d'arguments doit être égal à 1");
}
}
}
Solution 2
// on suppose qu’on a une seule classe TestPalindrome avec 3 méthodes
public class TestPalindrome {
public static String inverse(String s){
int l=s.length();
char [] s1 = new char[l];
for (int i=0; i<l; i++) {
s1[l-1-i]= s.charAt(i);
}
return new String (s1);
}
public static boolean isPalindrom(String s){
String s1=inverse(s);
return s1.equals(s);
}
public static void main(String[] args) {
try {
String s = args[0];
boolean b=isPalindrom(s);
System.out.println("L'iverse de la chaine: "+s+" est : "+inverse(s));
System.out.println("La chaine: "+s+" est un palindrom :"+b);
} catch (ArrayIndexOutOfBoundsException exc) {
System.out.println("Nombre d'arguments doit être égal à 1");
}
}
}
Exercice 3:
1. Considérons la classe «CalcFactorielle» définie ci-dessous. Ecrire la méthode main() qui doit récupérer
un entier n sur la ligne de commande, appelle la méthode « fact(n)» et ensuite affiche n!.

SMI-S5 Solution TP-4 : POO-Java, 2012-2013 4


Programme Java Exemples d’exécutions:
public class CalcFactorielle { > java CalcFactorielle 6
public static int fact(int k) { // calcule k! 6! = 720
> java CalcFactorielle -2
int f=1; // f=k!
-2! = 1
for (int i=1; i<=k; i++) > java CalcFactorielle 5.8
f=f*i; Exception in thread "main"
return f; java.lang.NumberFormatException: 5.8
} > java CalcFactorielle
public static void main(String[] args) { Exception in thread "main"
// … java.lang.ArrayIndexOutOfBoundsException
}
Solution
public static void main(String[] args) {
int n=Integer.parseInt(args[0]);
int f=fact(n);
System.out.println(n+" ! = "+f);
}
Remarque :
- Il n’est pas nécessaire de créer un objet de type CalcFactorielle et ensuite appeler la
méthode fact() pour cette objet. Par exemple
CalcFactorielle objA=new CalcFactorielle();
int f= ObjA.fact(n);
car la méthode fact() est static donc indépendante de l’objet.
- La méthode fact() retourne un entier de type int, donc le résultat de l’appel doit être
affecté à une variable de type int.
2. Dans cette question on s’intéresse à la gestion des différentes erreurs qui peuvent se produire.
- Modifiez la méthode «fact()» pour qu’elle puisse générer une exception de type «ExceptionNegatif»
(classe à définir) si on veut calculer la factorielle d'un entier négatif.
- Réécrire la méthode main() afin de traiter toutes les exceptions mentionnées sur les exemples
d’exécutions ci-dessus.
Solution :
class ExceptionNegatif extends Exception {
public ExceptionNegatif(String msg){
super(msg);
}
}
public class CalcFactorielle {
public static int fact(int k) throws ExceptionNegatif {
int f=1;
if (k<0) throw new ExceptionNegatif(k+": calcul de la factorielle d'un entier négatif ");
for (int i=1; i<=k; i++)
f=f*i;
return f;
}
public static void main(String[] args) {
try {
int n=Integer.parseInt(args[0]);
int f=fact(n);
System.out.println(n+"! = "+f);
}

SMI-S5 Solution TP-4 : POO-Java, 2012-2013 5


catch (ExceptionNegatif e){
System.out.println(e.getMessage());
}
catch (java.lang.NumberFormatException e){
System.out.println("Il faut saisir un entier ");
}
catch (java.lang.ArrayIndexOutOfBoundsException e){
System.out.println("Manque d'arguments sur la ligne de commande ");
}
}
}
Remarque :
- Le tableau args[] contient les arguments passés sur la ligne de commandes. Attention : les
arguments sont des chaines de caractères de type String, il faut ensuite les convertir suivant les
besoins. Par exemple Integer.parseInt(args[0]); convertit le premier argument en un entier de
type int.
- Ne pas rajouter else après l’instruction if.
if (k<0) throw new ExceptionNegatif(k+": calcul de la factorielle d'un entier négatif ");
else // n’est pas nécessaire.
for (int i=1; i<=k; i++)
f=f*i;
- L’instruction : int n=Integer.parseInt(args[0]); doit être mis dans le bloc try afin de pouvoir
traiter les exceptions générées par la lecture sur la ligne de commande.
3. Lorsque la valeur de n est « très grande » (dépasse une limite à calculer), l’exécution du programme
retourne un résultat erroné (voir l’exemple d’exécution ci-dessous).
Exemple d’exécution :
> java CalcFactorielle 20
20! = -2102132736
- Ecrire une classe nommée « ExceptionGrand » qui définit une exception qui sera levée si on calcule
la factorielle d'un entier « très grand ».
- Mettre à jour la méthode «fact()» pour qu’elle puissent lancer les deux exceptions de types
«ExceptionNegatif» et « ExceptionGrand », définies précédemment.
Indication : La valeur limite de n peut être déterminée pendant les étapes de calcul de la factorielle.
- Mettre à jour la méthode main() afin de traiter toutes les exceptions envisagées.
Solution :
- De la relation i!=i*(i-1)! on déduit que s’il n’y a pas d’erreur de calcul, alors on a : i!/(i-1)!=i.
- Dans une variable, par exemple f2, on sauvegarde la valeur de i! et dans une autre variable, par
exemple f1, on sauvegarde (i-1)!.
- On teste : si (f2/f1) != i alors on s’arrête car il y a erreur : la valeur maximale est atteinte, donc
on doit traiter l’exception. Sinon on continue

class ExceptionNegatif extends Exception {


public ExceptionNegatif(String msg){
super(msg);
}
}
class ExceptionGrand extends Exception {
public ExceptionGrand(String msg){
super(msg); }
}
public class CalcFactorielle {
public static int fact(int k) throws ExceptionNegatif, ExceptionGrand {
int f1=1,f2=1;
if (k<0) throw new ExceptionNegatif (k+": calcul de la factorielle d'un entier négatif ");
SMI-S5 Solution TP-4 : POO-Java, 2012-2013 6
for (int i=1; i<=k; i++) {
f2=f1*i; // f2 = i! et f1=(i-1)!
if ((f2/f1)!=i) throw new ExceptionGrand(k+": est grand. Entrer un entier <= "+(i-1));
f1=f2;
}
return f2;
}
public static void main(String[] args) {
try {
int n=Integer.parseInt(args[0]);
int f=fact(n);
System.out.println(n+"! = "+f);
}
catch (ExceptionNegatif e){
System.out.println(e.getMessage());
}
catch (ExceptionGrand e){
System.out.println(e.getMessage());
}
catch (java.lang.NumberFormatException e){
System.out.println("Il faut saisir un entier ");
}
catch (java.lang.ArrayIndexOutOfBoundsException e){
System.out.println("Manque d'arguments sur la ligne de commande ");
}
}
}

SMI-S5 Solution TP-4 : POO-Java, 2012-2013 7

Potrebbero piacerti anche