corrigé

Transcription

corrigé
L2 année 2015-2016
TD 3 -POO et langage JAVA
corrigé
Exercice 1 : Cryptographie
Polybe, un écrivain grec (205 - 126 avant JC), semble être à l'origine du premier
procédé de chiffrement par substitution connu.
C'est un système basé sur un carré
de 25 cases, comme montré dans
l'applet ci-contre. Chaque lettre peut
être représentée par un groupe de 2
chiffres : celui de sa ligne et celui de
sa colonne. Ainsi a=11, g=22, u=45 etc.
1
2
3
4
5
1
a
f
l
q
v
2
b
g
m
r
w
3
c
h
n
s
x
4
d
i-j
o
t
y
5
e
k
p
u
z
Les cryptologues modernes ont vu dans le "carré de 25" plusieurs caractéristiques
extrêmement intéressantes :

La conversion de lettres en chiffres
La réduction du nombre de symboles

La représentation de chaque lettre par des éléments séparés.

Écrire un programme en JAVA de cryptage d’un message contenu dans un tableau de N
caractères alphabétiques minuscules en un message de 2N nombres compris entre 1 et
5 comme l’indique l’exemple ci-dessus.
On n’oubliera pas de traiter la confusion des caractères ‘i’ et ‘j’. Proposer pour cela une
convention de traitement.
Écrire un programme en JAVA de décryptage d’un message contenu dans un tableau de
2N entiers en un message de N caractères alphabétiques minuscules restituant la
chaîne initiale cryptée par l’algorithme précédent. (On supposera que ce tableau ne
contient que des nombres compris entre 1 et 5) .
public class VG {
static int i,j;
static final int Nmax =5;
}
1/10
import java.util.*;
public class Main {
public static void Recherche(char c,char Cle[][])
{
int trouve=0;
VG.i=0;
while ((trouve==0) && (VG.i<VG.Nmax)){
VG.j=0;
while ((trouve==0) && (VG.j<VG.Nmax)) {
if (Cle[VG.i][VG.j]==c) trouve=1;
else {
VG.j=VG.j+1;
}
}
VG.i=VG.i+1;
}
}
public static char toChar(int codeASCII) {
return (char)codeASCII;
}
public static int toASCII(char lettre) {
return (int)lettre;
}
public static void main(String[] args) {
char Cle[][]=new char [VG.Nmax][VG.Nmax];
int i,j,k;
for (i=0;i<VG.Nmax;i++)
for (j=0;j<VG.Nmax;j++){
if ((i<=1)&& (j<=3))
Cle[i][j]=toChar(toASCII('a')+VG.Nmax*i+j);
else Cle[i][j]=toChar(toASCII('b')+VG.Nmax*i+j);
}
Cle[0][4]='e';
/* Affichage de la clé */
for (i=0;i<VG.Nmax;i++){
for (j=0;j<VG.Nmax;j++)
System.out.print(Cle[i][j]);
System.out.println();
}
char c;
int msgCrypter[]= new int[200];
int LongMsg;
Scanner in = new Scanner (System.in);
System.out.println("\n Donnez le message à crypter : ");
String msgInitial= in.nextLine();
LongMsg=msgInitial.length();
int l=0;
for (k=0;k<LongMsg;k++) {
c=msgInitial.charAt(k);
Recherche(c,Cle);
msgCrypter[l]=VG.i;
msgCrypter[l+1]=VG.j+1;
l=l+2;
}
System.out.println(" \n bonjour : voici le message crypte ");
for (k=0; k<2*LongMsg;k++)
System.out.print(msgCrypter[k]);
System.out.println(" \n bonjour : voici le message decrypte
");
for (k=0; k<2*LongMsg;k=k+2){
i=msgCrypter[k]-1;
j=msgCrypter[k+1]-1;
System.out.print(Cle[i][j]);
}
in.close();
}
}
2/10
///// pour lever l’ambigüité entre i et j on prendra le codage 2-4 pour i et 0-0 pour j
public static void main(String[] args)
{
char Cle[][]=new char [VG.Nmax][VG.Nmax];
int i,j,k;
for (i=0;i<VG.Nmax;i++)
for (j=0;j<VG.Nmax;j++){
if ((i<=1)&& (j<=3))
Cle[i][j]=toChar(toASCII('a')+VG.Nmax*i+j);
else Cle[i][j]=toChar(toASCII('b')+VG.Nmax*i+j);
}
Cle[0][4]='e';
/* Affichage de la clé */
for (i=0;i<VG.Nmax;i++){
for (j=0;j<VG.Nmax;j++)
System.out.print(Cle[i][j]);
System.out.println();
}
char c;
int msgCrypter[]= new int[200];
int LongMsg;
Scanner in = new Scanner (System.in);
System.out.println("\n CRYPTO 3
Donnez le message à crypter : ");
String msgInitial= in.nextLine();
LongMsg=msgInitial.length();
int l=0;
for (k=0;k<LongMsg;k++)
{
c=msgInitial.charAt(k);
if(c=='j') {
msgCrypter[l]=0;
msgCrypter[l+1]=0;
}
else {
Recherche(c,Cle);
msgCrypter[l]=VG.i;
msgCrypter[l+1]=VG.j+1;
}
l=l+2;
}
System.out.println(" \n bonjour : voici le message crypte ");
for (k=0; k<2*LongMsg;k++)
System.out.print(msgCrypter[k]);
System.out.println(" \n bonjour : voici le message decrypte
");
for (k=0; k<2*LongMsg;k=k+2){
if ((msgCrypter[k]==0)&&(msgCrypter[k+1]==0))
System.out.print("j");
else {
i=msgCrypter[k]-1;
j=msgCrypter[k+1]-1;
System.out.print(Cle[i][j]);
}
}
in.close();
}
}
3/10
Exercice 2 : Les tours de Hanoi
Étant donné trois piles, et n entiers tous différents empilés sur la première, les plus petits au dessus
des plus grands : un déplacement consiste à choisir une pile A non vide, et à enlever l’entier au
sommet pour le mettre au sommet d’une autre pile B, si le sommet de cette pile n’est pas un entier
plus petit (sinon, le déplacement est impossible).
On veut déplacer tous les entiers de la première pile sur la seconde, en se servant de la dernière.
L’algorithme proposé est le suivant : Pour déplacer n entiers de la pile A sur la pile C en utilisant la
pile B, on déplace (récursivement) n −1 sommets de A vers B, puis on déplace l’entier restant sur le
sommet de la pile A sur la pile C, et on déplace (récursivement) n −1 sommets de B vers C.
1. Définir une classe Hanoi qui représente le jeu : ses attributs seront trois piles et le nombre
d’entiers. Définissez d’ores et déjà une classe principale et une méthode main pour tester petit à petit
votre travail.
2. Définir le constructeur qui initialise le jeu à partir d’un nombre d’entiers à empiler et initialise les
piles dans la situation de départ.
3. Définir la méthode affiche qui affiche le contenu des trois piles sur la console.
4. Définir la méthode privée deplace et la méthode joue qui lance les déplacements.
5. Enfin, finaliser la classe principale et la méthode static main qui à partir d’un entier saisi en
ligne de commande initialise et lance le jeu.
4/10
Correction :
//fichier Hanoi.java
public class Hanoi{
Pile depart ;
Pile arrivee ;
Pile intermediaire ;
int nbEntiers ;
public Hanoi(int nbEntiers){
this.nbEntiers=nbEntiers ;
// construction des trois piles
depart = new Pile(nbEntiers) ;
arrivee = new Pile(nbEntiers) ;
intermediaire = new Pile(nbEntiers) ;
// remplissage de la pile de départ avec le premiers entiers
for(int i = 0; i<nbEntiers;i++){
depart.push(i) ;
}
}
public void affiche(){
System.out.println("Pile de depart :" + depart) ;
System.out.println("Pile intermediaire :" + intermediaire) ;
System.out.println("Pile d’arrivee :" + arrivee) ;
}
private void deplace(Pile A,Pile C,Pile B,int n){
if (n != 0) {
deplace(A,B,C,n-1) ;
C.push(A.pop()) ;
deplace(B,C,A,n-1) ;
}
}
public void joue(){
deplace(depart,arrivee,intermediaire,nbEntiers) ;
}
}
//fichier JeuHanoi.java
public class JeuHanoi{
public static void main(String[] argv){
Hanoi jeu = new Hanoi(4) ;
jeu.affiche() ;
jeu.joue() ;
jeu.affiche() ;
}
}
5/10
Exercice 3 : Gestion de comptes bancaire
Un compte bancaire peut être de 2 types (compte courant, compte rémunéré). Chaque compte est identifié par
son numéro, son titulaire et la somme d’argent disponible qu’on appelle solde.
Sur chaque compte bancaire, des opérations ont lieu. Il peut s’agir de retrait d’argent (on décrémente si
possible le solde d’une somme donnée), le dépôt (on augmente le solde d’un montant donné) et la consultation
(on retourne la somme disponible sur le compte)
Dans le cas d’un solde impossible (insuffisant) on lèvera une exception de type provisionInsuffisanteErreur
définie séparément.
Travail à faire :



Décrire la classe CompteBancaire permettant de représenter un compte.
Définir un constructeur permettant de construire un compte en fixant le numéro, le titulaire et le solde
initial.
Écrire les méthodes suivantes :
1. deposer : qui permet de déposer un montant dans un compte
2. retirer : qui permet le retrait d’un montant d’un compte
3. afficher : qui permet d’afficher le solde d’un compte
4. virerVersement : qui permet d’effectuer un montant d’un compte vers un autre.
public class Compte {
String Titulaire;
int Numero;
double Solde;
public Compte(String Titulaire, int Numero, double Solde){
this.Titulaire=Titulaire;
this.Numero=Numero;
this.Solde=Solde;
}
public void deposer(double montant){
this.Solde=this.Solde+montant;
}
public void retirer(double montant){
if (this.Solde<montant ) throw new provisionInsuffisanteErreur() ;
else this.Solde=this.Solde-montant;
}
public void afficher(){
System.out.println("Le solde du compte N°"+ this.Numero+
+this.Titulaire+ " est de " + this.Solde) ;
}
" de "
public double getSolde(){
return this.Solde;
}
public void virerVersement(Compte c, double montant){
c.retirer(montant);
this.deposer(montant);
}
class provisionInsuffisanteErreur extends Error {
}
}
6/10
Dans un second temps, on souhaite avoir la possibilité de permettre un découvert sur un compte (un retrait
conduirait à un solde négatif) ou la possibilité d’accorder une rémunération des dépôts sur un compte (compte
rémunéré).
Ces cas n’ont pas été prévus dans la classe CompteBancaire.
Travail à faire :

Définir les classes dérivées de la classe CompteBancaire permettant de représenter les comptes
bancaires à découvert et les comptes bancaires rémunérés.
On note qu’un compte à découvert doit avoir un découvert maximum autorisé et un compte rémunéré est
défini par son taux de rémunération.



Écrire la méthode fixerDecouvertMax qui permet de fixer le montant du découvert autorisé.
Écrire la méthode fixerTaux qui permet de fixer le taux de rémunération
Écrire la méthode retirer qui permet de retirer un montant d’un compte à découvert ou d’un
compte rémunéré.
public class CompteADecouvert extends Compte{
double decouvertMax;
public CompteADecouvert(String Titulaire, int Numero, double Solde, double
decouvertMax){
super(Titulaire,Numero, Solde);
this.decouvertMax=decouvertMax;
}
public void fixerDecouvert(double montant){
this.decouvertMax=montant;
}
public void retirer(double montant){
if (this.Solde-montant<-decouvertMax ) throw new
provisionInsuffisanteErreur() ;
else this.Solde=this.Solde-montant;
}
}
public class CompteRemunere extends Compte{
double Taux;
double Interet;
public void fixerTaux(double montant){
this.Taux=montant;
}
public CompteRemunere(String Titulaire,int Numero, double Solde, double
montant,double Taux){
super(Titulaire,Numero, Solde);
this.Interet=0.0;
fixerTaux(Taux);
}
public void afficherCompte(){
super.afficher() ;
System.out.println(" au taux de " + this.Taux) ;
}
}
7/10
Travail à faire : De la classe CompteRemunere, écrire la méthode afficherCompte() sachant qu’afficher les
données d’un compte rémunéré revient à afficher les données d’un compte suivies du taux de rémunération.
public void afficherCompte(){
super.afficher() ;
System.out.println(" au taux de
}
" + this.Taux) ;
On souhaite contrôler la validité des données saisies pour un compte bancaire ne pouvant être que de type
courant, rémunéré ou joint.
Travail à faire :
Écrire la méthode ControleType() qui retourne à la suite de la saisie du type de compte un String valant
« Courant » , « Rémunéré » ou « Joint ».
private static String controleType() {
char tempc ;
String tempS = "courant" ;
Scanner in = new Scanner(System.in) ;
do {
System.out.print ("Type du compte C : courant – R : rémunéré – J : joint : ") ;
tempc = in.nextLine().charAt(0);
} while (tempc !='C' && tempc !='R' && tempc !='J'&& tempc !='c' && tempc !='r' &&
tempc !='j');
switch (tempc) {
case 'c' :
case 'C' : tempS="Courant";
break;
case 'r' :
case 'R' : tempS="Rémunéré";
break;
case 'J' :
case 'j' : tempS="Joint";
break;
}
return tempS;
}
Travail à faire :
Dans la classe Compte, sachant qu’un solde initial ne peut être négatif à la création du compte, écrire la
méthode ControleValeurInit()
private static Double controleValeurInit() {
double tempVal ;
Scanner in = new Scanner(System.in) ;
do {
System.out.print ("Valeur Initiale du compte : ") ;
tempVal = in.nextDouble();
} while (tempVal<=0);
return tempVal;
}
8/10
import java.util.*;
public class TestCompte {
private static String controleType() {
char tempc ;
String tempS = "courant" ;
Scanner in = new Scanner(System.in) ;
do {
System.out.print ("Type du compte C : courant – R : rémunéré – J : joint : ") ;
tempc = in.nextLine().charAt(0);
} while (tempc !='C' && tempc !='R' && tempc !='J'&& tempc !='c' && tempc !='r' &&
tempc !='j');
switch (tempc) {
case 'c' :
case 'C' : tempS="Courant";
break;
case 'r' :
case 'R' : tempS="Rémunéré";
break;
case 'J' :
case 'j' : tempS="Joint";
break;
}
return tempS;
}
private static Double controleValeurInit() {
double tempVal ;
Scanner in = new Scanner(System.in) ;
do {
System.out.print ("Valeur Initiale du compte : ") ;
tempVal = in.nextDouble();
} while (tempVal<=0);
return tempVal;
}
public static void main(String[] args) {
System.out.println("Bonjour ICI Ma Banque ") ;
String Message=controleType();
System.out.println("vous venez de créer un compte "+Message) ;
Double SoldeInitial=controleValeurInit();
System.out.println("vous venez de créer un compte d'un solde initial de "+SoldeInitial) ;
int
num1 = 12345 ;
int
num2 = 45565 ;
int
num3 = 35897 ;
int
num4 = 26897 ;
Compte c1=new Compte("HAMOUDA",num1,2000.0);
Compte c2=new Compte("AMIRA",num2,500.0);
Compte c3=new Compte("DURAND",num3,600.0);
Compte c4;
c1.afficher();
c2.afficher();
c3.afficher();
System.out.println("vous venez de déposer 600 euros sur le compte c1 ") ;
c1.deposer(600);
c1.afficher();
System.out.println("vous venez de retirer 50 euros sur le compte c2 ") ;
c2.retirer(50);
c2.afficher();
9/10
System.out.println("vous venez de virer un versement de 60 euros du compte c3 sur le
compte c1 ") ;
c1.virerVersement(c3, 60);
c1.afficher();
c3.afficher();
c2.retirer(80);
c4= new CompteADecouvert("DUPONT",num4,2500.0,200.0);
c4.virerVersement(c1, 50);
c4.retirer(2800);
c1.afficher();
c4.afficher();
}
}
10/10

Documents pareils