M1202 - TP Bonus

Durée : 3h00




Objectifs




Au menu

  1. Consignes
  2. Paramètres d'un programme Java
  3. Chargement et affichage d'un fichier texte
  4. Remplacement des caractères spéciaux d'un texte
  5. Extraction des mots d'un texte
  6. Alignement de deux textes

Lisez attentivement cet énoncé de TP/TD en suivant les instructions. En cas d'interrogation, faites appel à moi, que ce soit pour en savoir plus sur un des points abordés pendant le TP, ou pour savoir comment effectuer une des tâches demandées (numérotées pour pouvoir y faire référence simplement).

Surtout ne restez pas bloqué(e) sur une des questions. Entre parenthèses, à côté des titres de sous-sections, est indiqué le temps que vous avez dû passer à effectuer les étapes précédentes.

Au cours de ce TP, nous allons traiter des fichiers textes stockés sur le disque dur, dont l'adresse est fournie en paramètre du programme.

Votre objectif minimal doit être d'arriver jusqu'à la fin de la section D.

Lors de l'appel d'un programme en Java, par la commande java nom_du_programme, il est possible de faire suivre le nom du programme par des paramètres séparés par des espaces. Par exemple, si on veut indiquer deux paramètres param1 et param2 pour le programme TD5, on exécutera dans le terminal la commande suivante :
java TD5 param1 param2

Ces paramètres sont alors stockés dans un tableau de chaînes de caractères, appelé arg, qui est donné comme paramètre d'entrée de la fonction main. Ceci explique que la déclaration de la fonction main d'un programme Java est toujours de la forme public static void main(String[] arg) dans les exemples que nous avons vus jusqu'à présent.

Nous allons tout d'abord voir comment compter et récupérer ces paramètres.

Pour cela, commencez par créer un dossier dédié à ce TP5 (de la même manière qu'aux TP précédents), puis enregistrez-y ce fichier TP5.java, ainsi que TP5Apollinaire.txt et TP5Hugo.txt.

Maintenant, ajoutez dans le main une instruction qui permet d'afficher le nombre de paramètres. Testez-la en compilant TD5.java, puis en exécutant TD5 avec un, deux, ou aucun paramètre.

Paramètres d'un programme Java
En utilisant un test avant l'affichage dans le main, faites afficher un message du type "x parametre en entree du programme.", où x correspond au nombre de paramètres en entrée du programme, et le mot "parametre" est bien accordé, c'est-à-dire qu'il est au pluriel si x est strictement supérieur à 1. Vous devez donc obtenir un résultat similaire à celui de la copie d'écran ci-contre.

Faites ensuite un parcours du tableau arg pour afficher tous les paramètres en entrée du programme, précédés de Parametre x :, où x est le numéro du paramètre (le premier paramètre a pour numéro 0). Vous devez obtenir un résultat similaire à celui de la copie d'écran ci-contre.

Une fonction permettant de récupérer le contenu d'un fichier texte du disque dur a déjà été programmée dans le fichier TP5.java. Elle s'appelle ouvreFichier et fonctionne de la façon suivante :
Affichage du contenu d'un fichier texte

Ajoutez dans la fonction main le code permettant de stocker, dans un tableau de chaînes de caractères appelé texte, les lignes d'un fichier texte dont l'adresse est donnée comme premier paramètre du programme Java.
Indication à surligner si vous bloquez : dans la fonction main, récupérez dans une variable adresse le premier paramètre en entrée du programme Java, puis appelez la fonction ouvreFichier sur cette variable adresse, et stockez le résultat renvoyé par cette fonction dans un tableau de chaînes de caractères appelé texte. Puis parcourez ce tableau texte pour afficher le contenu de chacune de ses cases, l'une après l'autre.

Avant l'affichage de chaque ligne, affichez le numéro de ligne

A cause des numéros 1, 2, 3, etc., qui sont plus courts que 10, 11, 12, etc., qui sont eux-mêmes plus courts que 101, 102, 103, etc., certaines lignes sont un peu décalées. Utilisez un test pour ajouter suffisamment de zéros avant le numéro de ligne, pour que chaque numéro de ligne ait exactement trois chiffres (il y aura donc le même alignement pour toutes les lignes de 1 à 999). Vous devez obtenir un résultat similaire à celui de la copie d'écran ci-contre. Les lettres accentuées s'affichent mal dans le terminal. On va donc écrire une fonction remplaceCaracteres qui prend en entrée une chaîne de caractères, et renvoie cette chaîne où les lettres "é", "è" et "ê" ont été remplacées par "e", la lettre "à" a été remplacée par "a", etc.

Remarque sur la fonction caractere : Vous pouvez aller voir le code de la fonction caractere, dans le fichier TP5.java, pour découvrir comment on peut traiter les chaînes de caractères en Java. L'instruction return chaineCar.substring(i-1,i); est utilisée, ce qui signifie que la fonction renvoie la sous-chaîne de la chaîne de caractères chaineCar fournie en entrée, allant du caractère numéroté i-1 au caractère numéroté i. Remarquez que les caractères d'une chaîne de caractères en Java sont numérotés à partir de zéro (ce qui explique le "i-1"). Remarquez aussi que contrairement à l'habitude où les paramètres d'une fonction sont tous mis entre parenthèses lors de l'appel de la fonction, ici, le paramètre chaineCar est mis avant le nom de la fonction, séparé d'un point. Ceci vient du fait que Java est un langage objet (ce que vous verrez en détails au module INF250) et s'interprète de la manière suivante : on peut appliquer toute une liste d'actions sur l'objet chaineCar qui est une chaîne de caractères, notamment : récupérer ce qui se trouve entre deux positions de la chaîne de caractères avec substring.
Écrivez cette fonction remplaceCaracteres, puis utilisez-la pour afficher une version du poème sans caractères spéciaux. Pour cela, vous pouvez (devez ?) utiliser la fonction caractere qui prend en entrée une chaîne de caractères chaineCar et un entier i, et renvoie le i-ième caractère ; ainsi que la fonction chainesEgales qui prend en entrée deux chaînes de caractères, et renvoie true si elles sont égales, false sinon.
Indication à surligner si vous bloquez : Vous allez recréer une nouvelle chaîne de caractères à partir de la chaîne chaineCar, en partant d'une nouvelle chaîne vide : pour chaque caractère de chaineCar, soit vous l'ajoutez à la nouvelle chaîne, s'il n'a pas d'accent ; soit vous ajoutez sa version sans accent à la nouvelle chaîne, s'il a un accent.

Le problème de la fonction remplaceCaracteres précédente est qu'elle nécessite de définir les lettres à remplacer à l'intérieur du code de la fonction. Ainsi, si vous voulez choisir d'autres caractères à remplacer (par exemple pour la gestion des caractères spéciaux espagnols ou allemands), il faudra modifier cette fonction. Une solution préférable est de fournir en entrée de la fonction un tableau caracteres de chaînes de caractères, dont chaque case contient un caractère spécial à remplacer (par exemple le tableau {"é","è","ê","à","ù"}), ainsi qu'un deuxième tableau remplacants qui contient dans chaque case le caractère à utiliser pour le remplacement (par exemple le tableau {"e","e","e","a","u"}). Un avantage du langage Java est que, pour cela, vous pouvez garder le même nom de fonction, remplaceCaracteres, car les entrées sont différentes de l'autre fonction remplaceCaracteres définie plus haut. Écrivez cette nouvelle fonction remplaceCaracteres. Vous pouvez bien sûr commencer par un copier-coller de la précédente fonction remplaceCaracteres.

Créez deux tableaux de chaînes de caractères caracteres et remplacants dans la fonction main, et utilisez-les dans l'appel de la fonction remplaceCaracteres.

Remarque : pour créer un tableau tab déjà déclaré, en utilisant l'"écriture compressée", il ne suffit pas d'écrire, par exemple, tab = {"*","*","*"}, mais il faut repréciser le type du tableau, avec une instruction du type tab = new String[]{"*","*","*"}.

Remplacez toutes les cases du tableau remplacants par la chaîne de caractères "*" pour voir si cela remplace effectivement toutes les lettres accentuées par des étoiles.

Appelez, depuis la fonction main, la fonction remplaceCaracteres avec deux tableaux en entrée, pour remplacer tous les signes de ponctuation par des espaces.

Cette partie du TP sera poursuivie au prochain TP...

Écrivez une fonction dansTableau qui prend en entrée une chaîne de caractères mot et un tableau de chaînes de caractères dico et renvoie true si mot apparaît dans une case de dico, et false sinon.

Écrivez une fonction ajouteFinTableau qui prend en entrée une chaîne de caractères mot et un tableau de chaînes de caractères dico, et renvoie le tableau dico à la fin duquel le mot mot a été ajouté. Attention, comme il est impossible de changer la taille d'un tableau, il va falloir recopier le tableau dico dans un tableau plus grand d'une case, et ajouter mot dans la dernière case de ce nouveau tableau.

Écrivez une fonction insereDansTableau, qui utilise les deux fonctions précédentes, et prend en entrée une chaîne de caractères mot et un tableau de chaînes de caractères dico, et renvoie le tableau dico dans lequel le mot mot a été ajouté s'il n'y était pas déjà.

Écrivez une fonction creeDico, qui prend en entrée deux tableaux de chaînes de caractères, un nommé texte, qui correspond à un texte (une ligne du texte par case du tableau), et l'autre nommé dico qui correspond à une liste de mots, et ajoute dans dico tous les mots de texte (sauf s'ils sont déjà dans dico).

Utilisez la fonction creeDico depuis la fonction main, pour afficher la liste des mots du texte fourni en paramètre du programme Java. Essayez-la sur les deux textes TP5Hugo.txt et TP5Apollinaire.txt, et sur un autre texte de votre choix. Nous allons voir dans cette section comment aligner le mieux possibles deux versions d'un même texte avec de légères différences. Étant donné deux tableaux de chaînes de caractères t1 et t2, alignez le tableau t2 avec t1, c'est-à-dire créez une fonction aligneTableaux qui crée un nouveau tableau PositionDansT1 donnant pour chaque mot de t2 la position dans t1 du mot identique correspondant. Si aucun mot ne correspond, indiquez l'entier -1. Vous commencerez par proposer un algorithme glouton, c'est-à-dire un algorithme qui va, successivement pour chaque mot de t1, chercher parmi les k prochains mots de t2 pas encore associés à t1 (prendre par exemple k=10).

Testez votre algorithme sur les deux textes suivants avec k=20 :

Cet algorithme "glouton" pose plusieurs problèmes :

Comprenez et codez en Java l'algorithme de Needleman Wunsch pour aligner les deux tableaux. En cas de difficultés à comprendre l'algorithme, la page Wikipedia anglaise est davantage illustrée.