Une classe Repertoire avec recherche dichotomique

Transcription

Une classe Repertoire avec recherche dichotomique
Une classe Repertoire avec recherche dichotomique
import java.util.ArrayList;
public class Repertoire
{
private ArrayList<Personne> vect;
private int positionDicho(String nom)
/* SE :
indice,
l'ordre
*/
// SI :
si une personne ayant le nom passé en paramètre existe dans le répertoire, retourne son
sinon retourne l'indice à laquelle cette personne devrait être insérée (en respectant
lexicographique sur les noms) ; la recherche ignore la distinction majusucule/minuscule
recherche dichotomique itérative ; le nom passé en paramètre est mis en majuscules
{
nom = nom.toUpperCase(); // car vect ne contient que des noms en majuscule
int deb = 0;
int fin = vect.size()-1;
int milieu;
while (deb<=fin) // tant que debut et fin ne se croisent pas
{
milieu = (deb+fin)/2;
int compare = vect.get(milieu).getNom().compareTo(nom) ;
if (compare == 0)
// on a trouvé l’élément (à l’indice milieu)
return milieu;
else if (compare > 0)
// alors il est après milieu
fin = milieu - 1;
else deb = milieu + 1; // sinon il est avant milieu
}
return deb;
// pas trouvé; position à laquelle il faudrait l'insérer
}
private boolean existe(String nom, int position)
//
//
//
//
//
//
SE : retourne vrai si le répertoire contient une personne ayant ce nom à cette position ;
faux sinon.
Prérequis : position doit être un entier positif, mais pas forcément un indice valide
SI : le nom passé en paramètre est mis en majuscules ; cette méthode peut-être utilisée après
positionDicho pour déterminer si cette dernière a retourné la position où se trouve nom ou
bien la position où il faudrait l’insérer
{
nom = nom.toUpperCase();
return (position < vect.size() && vect.get(position).getNom().equals(nom));
}
On peut penser à une autre version de positionDicho : PositionDicho retourne un entier positif ou nul si l'élément
recherché existe (instruction' return milieu') et un entier négatif si l'élément n'existe pas (l'instruction 'return deb'
devient 'return – deb').
Ainsi,il n'est plus nécessaire d'appeler la méthode existe pour déterminer si l'entier retourné par positionDicho
correspond à la position de l'élément ou à la position où il devrait figurer. Il suffit de tester si cet entier est < ou non
à 0.
Il y a cependant un petit point à réparer dans cette idée. Lequel?
public Répertoire()
// SE : crée un répertoire vide
{vect =
= new ArrayList<Personne>();}
public void vider()
// SE : vide le repertoire
{
vect.clear();
}
Correction Répertoire (version dichotomique)
1
Quel paramètre pour la méthode ajouter? Une instance de Personne, ou les informations (nom, tel, date de
naissance) permettant de créer une instance de Personne dans la méthode
public boolean ajouter(Personne p)
//
//
//
//
//
//
//
//
//
//
SE : si une personne ayant le même nom que p existe dans le répertoire
(en ignorant la disctinction majuscule/minuscule),
ne fait rien et retourne faux ; sinon ajoute p dans le répertoire et retourne vrai
SI : la personne p est insérée au bon endroit dans le répertoire selon l'ordre lexicographique
du nom
On récupère dans i (1) soit l’emplacement où il faut insérer p (si le répertoire ne contient aucune
personne qui a le même nom) (2) soit l’emplacement où se trouve une personne qui a le même nom que
p. Pour savoir dans quel cas on se trouve, on appelle alors la méthode existe() qui
retourne VRAI si on est dans second cas (et on ne fait rien). Si la méthode retourne FAUX on est alors
dans le premier cas (et on insère la personne)
{
int i = positionDicho(p.getNom());
if (!existe(p.getNom(),i))
return vect.add(i,p); //return
else
return false;
true
}
public boolean retirer(String nom)
//
//
//
//
SE : si nom existe dans le répertoire (en ignorant la disctinction majuscule/minuscule),
retire la personne ayant ce nom et retourne vrai ;
sinon ne fait rien et retourne faux
SI : utilise la méthode existe()
{
int i = positionDicho(nom);
if (existe(nom,i))
return vect.remove(i);
else
return false;
// return true
}
public Personne retrouver(String nom)
//
//
//
//
SE : si nom existe dans le répertoire (en ignorant la disctinction majuscule/minuscule),
retourne une référence sur la personne ayant ce nom ;
sinon retourne null
SI : utilise la méthode existe
{
int i = positionDicho(nom);
if (existe(nom,i))
return vect.get(i);
else return null;
}
public String toString()
// SE : retourne la liste des personnes du répertoire, séparées par un espace ; chaque personne
est représentée par la chaîne "nom:tel" ; si le répertoire est vide, retourne la chaîne vide
{
String s = new String(); // ou bien s = "";
for (int i=0; i<vect.size(); i++)
s = s + vect.get(i) + " ";
// on appelle en fait vect.get(i).toString()
return s;
}
Remarque : On aurait aussi pu faire appel à la méthode toString() de la classe ArrayList, qui fait appel à la méthode
toString() de chacun des éléments du tableau et retourne une chaîne concaténant les résultats. Soit :
{
return vect.toString();
}
Correction Répertoire (version dichotomique)
2
o Méthodes à ajouter ou à modifier pour effectuer la recherche dichotomique de façon
récursive :
private int positionDicho(String nom)
{
nom = nom.toUpperCase();
return positionDichoRecursif(nom,0,vect.size()-1);
}
private int positionDichoRecursif(String nom, int deb, int fin)
// SE : recherche nom entre les indices deb et fin de l'ArrayList, même valeur de retour que
positionDicho
// Prérequis: deb et fin doivent être compris entre 0 et (taille de l'ArrayList -1)
// SI : méthode récursive ; appelée par postionDicho
{
if (deb>fin)
return deb;
else {
int milieu = (deb+fin)/2;
int compare = vect.get(milieu).getNom().compareTo(nom) ;
if (compare == 0)
return milieu;
else if (compare > 0)
return positionDichoRecursif(nom,deb,milieu-1);
else return positionDichoRecursif(nom,milieu+1,fin);
}
}
}
Correction Répertoire (version dichotomique)
3