package Dico;
/**La classe FastDictionary spécialise la classe AbstractDictionary
*Cette classe est une spécialisation du framework défini pas l'interface Dictionary et la classe AbstractDictionary
*Dans ce type de dictionnaire, les couples clé-valeur sont rangés et retrouvés à l'aide d'une technique de hachage*/
public class FastDictionary extends AbstractDictionary {
/**Ce constructeur définit un objet FastDictionary avec une taille de dictionnaire de 10 par défaut*/
public FastDictionary() {
tailleTab = 10;
tabCle = new Object[tailleTab];
tabValeur = new Object[tailleTab];
}
/**Ce constructeur définit un objet FastDictionary avec une taille de dictionaire passée en paramètre
*@param t taille du dictionnaire*/
public FastDictionary(int t) {
tailleTab = t;
tabCle = new Object[tailleTab];
tabValeur = new Object[tailleTab];
}
/**Cette méthode renvoie le nombre de couples clé-valeur contenus dans le dictionnaire
*Cette méthode est une redéfinition de la méthode size() de la classe AbstractDictionary qui supposait les couples tassés à gauche dans le dictionnaire. Un dictionnaire de type FastDictionary doit être parcouru en entier car il contient des trous
*@return Nombre d'éléments contenus dans le dictionnaire*/
protected int size() {
int cpt = 0;
for (int i = 0 ; i < tailleTab ; i++) {
if (tabCle[i] != null)
cpt++;
}
return cpt;
}
/**Cette méthode renvoie l'index auquel est rangée la clé passée en paramètre dans le receveur
*Cette méthode est une redéfinition de la méthode indexOf de la classe AbstractDictionary qui effectuait une recherche séquentielle. Pour un dictionnaire de type FastDictionary, l'index correspondant à la clé passée en paramètre est retrouvé à l'aide de la méthode de hachage
*@param key clé recherchée dans le dictionnaire
*@return index de la clé si elle a été trouvée, sinon -1*/
protected int indexOf(Object key) {
if (tailleTab == 0)
return -1;
int index = key.hashCode() % tailleTab;
if (index < 0)
index = (-1) * index;
int i = index;
if (tabCle[index] != key) {
do {
i++;
if (i == tailleTab)
i = 0;
} while( (i != index) && (tabCle[i] != key));
if (i == index)
return -1;
else
return i;
}
else
return index;
}
/**Cette méthode renvoie l'index auquel sera rangé un nouveau couple clé-valeur dans le dictionnaire
*Cet index est calculé à l'aide d'une technique de hachage : la méthode hashCode() est appliquée à la clé modulo la taille du dictionnaire
*Si un couple clé-valeur est déjà rangé dans le dictionnaire à cette position, le dictionnaire est parcouru de manière séquentielle jusqu'à obtenir l'index d'une case vide
*Cette méthode ne doit être appelée que dans le cas ou le dictionnaire ne contient pas déjà cette clé
*Si le dictionnaire est aux 3/4 plein, la taille du dictionnaire est augmentée de 25% par rapport à sa taille initiale, de manière à éviter au maximum les conflits de hachage
*@param key clé de l'élément à insérer
*@return index du nouvel élément dans le receveur*/
protected int newIndexOf(Object key) {
if (mustGrow())
grow();
int index = key.hashCode() % tailleTab;
if (index < 0)
index = (-1) * index;
while (tabCle[index] != null) {
index++;
if (index == tailleTab)
index = 0;
}
return index;
}
/**Cette méthode indique si le dictionnaire doit être agrandi ou non
*@return vrai si le receveur est aux 3/4 plein, faux sinon*/
protected boolean mustGrow() {
if (size() + 1 > (tailleTab * 3) / 4)
return true;
else
return false;
}
/**Cette méthode permet d'augmenter la taille du ditionnaire de 25%
*Les clés et les valeurs sont réinsérées dans les nouveaux tableaux en utilisant une technique de hachage
*L'index d'un couple est calculé en appliquant la méthode hashCode() à la clé modulo la taille du dictionnaire
*Si un couple clé-valeur est déjà rangé dans le dictionnaire à cette position, le dictionnaire est parcouru de manière séquentielle jusqu'à obtenir l'index d'une case vide*/
protected void grow() {
int fin = tailleTab;
if (tailleTab % 4 == 0)
tailleTab = tailleTab + tailleTab / 4;
else
tailleTab = tailleTab + tailleTab / 4 + 1;
if (tailleTab == 0)
tailleTab = 2;
Object[] newTabCle = new Object[tailleTab];
Object[] newTabValeur = new Object[tailleTab];
for (int i = 0 ; i < fin ; i++) {
if (tabCle[i] != null) {
int index = tabCle[i].hashCode() % tailleTab;
if (index < 0)
index = (-1) * index;
while (newTabCle[index] != null) {
index++;
if (index == tailleTab)
index = 0;
}
newTabCle[index] = tabCle[i];
newTabValeur[index] = tabValeur[i];
}
}
tabCle = newTabCle;
tabValeur = newTabValeur;
}
/*Test d'insertion d'un élément dans le dictionnaire
1) CRITERES
PRECONDITIONS:
-dictionnaire de taille 0 (T0) / dictionnaire de taille 1 (T1) / dictionnaire de taille quelconque (TN)
-0 élément dans le dictionnaire (D0) / 1 élément dans le dictionnaire (D1) / n*3/4 éléments dans le dictionnaire (DN3/4)
-élément dans dictionnaire (ED) / élément non dans dictionnaire (END)
POSTCONDITION:
-élément inséré (EI) / élément non inséré (ENI)
2) CLASSES D'EQUIVALENCE
POTENTIELLES : (T0 T1 TN) * (D0 D1 DN3/4) * (ED END) * (EI ENI)
EFFECTIVES : T0*D0*END*EI ;
T1*D0*END*EI ; T1*D1*ED*ENI ; T1*D1*END*EI ;
TN*D0*END*EI ; TN*D1*ED*ENI ; TN*D1*END*EI ; TN*DN3/4*ED*ENI ; TN*DN3/4*END*EI
*/
/*Test de recherche d'un élément dans le dictionnaire
1) CRITERES
PRECONDITIONS:
-dictionnaire de taille 0 (T0) / dictionnaire de taille 1 (T1) / dictionnaire de taille quelconque (TN)
-0 élément dans le dictionnaire (D0) / 1 élément dans le dictionnaire (D1) / n*3/4 éléments dans le dictionnaire (DN3/4)
POSTCONDITION:
-élément trouvé (ET) / élément non trouvé (ENT)
2) CLASSES D'EQUIVALENCE
POTENTIELLES : (T0 T1 TN) * (D0 D1 DN3/4) * (ET ENT)
EFFECTIVES : T0*D0*ENT ;
T1*D0*ENT ; T1*D1*ET ; T1*D1*ENT ;
TN*D0*ENT ; TN*D1*ENT ; TN*D1*ET ; TN*DN3/4*ENT ; TN*DN3/4*ET
*/
protected int testBoiteBlanche() {
int retour = 0;
//TEST N°1:
//Insertion : T0*D0*END*EI
//Recherche : T0*D0*ENT
System.out.println("\nTEST N°1:");
System.out.println("Recherche : Essai de recherche d'un élément dans un dictionnaire vide \nde taille 0");
System.out.println("Insertion : Essai d'insertion d'un élément dans un dictionnaire vide \nde taille 0");
FastDictionary dico = new FastDictionary(0);
if (dico.get("Platon") != null) {
System.out.println("Erreur : L'élément n'aurait pas du être trouvé");
System.out.println("TEST 1 Recherche ....................................................[FAILED]");
retour = -1;
}
else
System.out.println("TEST 1 Recherche ....................................................[OK]");
dico.put("Platon", "Philosophe grec");
if (!dico.containsKey("Platon")) {
System.out.println("Erreur : L'élément n'a pas été inséré");
System.out.println("TEST 1 Insertion ....................................................[FAILED]");
retour = -1;
}
else {
if (dico.tailleTab != 2) {
System.out.println("Erreur : La taille du dictionnaire est incorrecte");
System.out.println("TEST 1 Insertion ....................................................[FAILED]");
retour = -1;
}
else
System.out.println("TEST 1 Insertion ....................................................[OK]");
}
//TEST N°2:
//Insertion : T1*D0*END*EI
//Recherche : T1*D0*ENT
System.out.println("\nTEST N°2:");
System.out.println("Insertion : Essai d'insertion d'un élément dans un dictionnaire vide \nde taille 1");
System.out.println("Recherche : Essai de recherche d'un élément dans un dictionnaire vide \nde taille 1");
dico = new FastDictionary(1);
if (dico.get("Platon") != null) {
System.out.println("Erreur : L'élément n'aurait pas du être trouvé");
System.out.println("TEST 2 Recherche ....................................................[FAILED]");
retour = -1;
}
else
System.out.println("TEST 2 Recherche ....................................................[OK]");
dico.put("Platon", "Philosophe grec");
if (!dico.containsKey("Platon")) {
System.out.println("Erreur : L'élément n'a pas été inséré");
System.out.println("TEST 2 Insertion ....................................................[FAILED]");
retour = -1;
}
else {
boolean drapo = true;
if (dico.tailleTab != 2) {
System.out.println("Erreur : La taille du dictionnaire est incorrecte");
System.out.println("TEST 2 Insertion ....................................................[FAILED]");
retour = -1;
drapo = false;
}
if (dico.size() != 1) {
System.out.println("Erreur : Le dictionnaire devrait contenir un seul élément");
System.out.println("TEST 2 Insertion ....................................................[FAILED]");
retour = -1;
drapo = false;
}
if (drapo)
System.out.println("TEST 2 Insertion ....................................................[OK]");
}
//TEST N°3:
//Insertion : T1*D1*ED*ENI
//Recherche : T1*D1*ET
System.out.println("\nTEST N°3:");
System.out.println("Insertion : Essai d'insertion d'un élément dans un dictionnaire \nde taille 1\nLe dictionnaire contient 1 élément, l'élément à insérer est connu");
System.out.println("Recherche : Essai de recherche d'un élément dans un dictionnaire \nde taille 1\nLe dictionnaire contient 1 élément\nL'élément se trouve en position 0");
if (dico.get("Platon") == null) {
System.out.println("Erreur : L'élément aurait du être trouvé");
System.out.println("TEST 3 Recherche ....................................................[FAILED]");
retour = -1;
}
else
System.out.println("TEST 3 Recherche ....................................................[OK]");
if (!dico.containsKey("Platon")) {
System.out.println("Erreur : L'élément devrait se trouver dans le ditionnaire");
System.out.println("TEST 3 ..............................................................[FAILED]");
retour = -1;
}
else
System.out.println("TEST 3 Insertion ....................................................[OK]");
//TEST N°4:
//Insertion : T1*D1*END*EI
//Recherche : T1*D1*ENT
System.out.println("\nTEST N°4:");
System.out.println("Essai d'insertion d'un élément dans un dictionnaire de taille 1\nLe dictionnaire contient 1 élément, l'élément à insérer est inconnu");
System.out.println("Essai de recherche d'un élément dans un dictionnaire de taille 1\nLe dictionnaire contient 1 élément\nL'élément ne se trouve pas dans le dictionnaire");
if (dico.get("Euclide") != null) {
System.out.println("Erreur : L'élément n'aurait pas du être trouvé");
System.out.println("TEST 4 Recherche ....................................................[FAILED]");
retour = -1;
}
else
System.out.println("TEST 4 Recherche ....................................................[OK]");
dico.put("Euclide", "Mathématicien grec");
if (!dico.containsKey("Euclide")) {
System.out.println("Erreur : L'élément n'a pas été inséré");
System.out.println("TEST 4 Insertion ....................................................[FAILED]");
retour = -1;
}
else {
boolean drapo = true;
if (dico.tailleTab != 3) {
System.out.println("Erreur : La taille du dictionnaire est incorrecte");
System.out.println("TEST 4 Insertion ....................................................[FAILED]");
retour = -1;
drapo = false;
}
if (dico.size() != 2) {
System.out.println("Erreur : Le nombre d'éléments est incorrect");
System.out.println("TEST 4 Insertion ....................................................[FAILED]");
retour = -1;
drapo = false;
}
if (drapo)
System.out.println("TEST 4 Insertion ....................................................[OK]");
}
//TEST N°5:
//Insertion : TN*D0*END*EI
//Recherche : TN*D0*ENT
System.out.println("\nTEST N°5:");
System.out.println("Insertion : Essai d'insertion d'un élément dans un dictionnaire vide \nde taille n");
System.out.println("Recherche : Essai de recherche d'un élément dans un dictionnaire vide \nde taille n");
dico = new FastDictionary(4);
if (dico.get("Platon") != null) {
System.out.println("Erreur : L'élément n'aurait pas du être trouvé");
System.out.println("TEST 5 Recherche ....................................................[FAILED]");
retour = -1;
}
else
System.out.println("TEST 5 Recherche ....................................................[OK]");
dico.put("Platon", "Philosophe grec");
if (!dico.containsKey("Platon")) {
System.out.println("Erreur : L'élément n'a pas été inséré");
System.out.println("TEST 5 Insertion ....................................................[FAILED]");
retour = -1;
}
else {
boolean drapo = true;
if (dico.tailleTab != 4) {
System.out.println("Erreur : La taille du dictionnaire est incorrecte");
System.out.println("TEST 5 Insertion ....................................................[FAILED]");
retour = -1;
drapo = false;
}
if (dico.size() != 1) {
System.out.println("Erreur : Le nombre d'éléments est incorrect");
System.out.println("TEST 5 Insertion ....................................................[FAILED]");
retour = -1;
drapo = false;
}
if (drapo)
System.out.println("TEST 5 Insertion ....................................................[OK]");
}
//TEST N°6:
//Insertion : TN*D1*ED*ENI
//Recherche : TN*D1*ET
System.out.println("\nTEST N°6:");
System.out.println("Insertion : Essai d'insertion d'un élément dans un dictionnaire \nde taille n\nLe dictionnaire contient 1 élément, l'élément à insérer est connu");
System.out.println("Recherche : Essai de recherche d'un élément dans un dictionnaire \nde taille n\nLe dictionnaire contient 1 élément\nL'élément recherché est connu");
if (dico.get("Platon") == null) {
System.out.println("Erreur : L'élément aurait du être trouvé");
System.out.println("TEST 6 Recherche ....................................................[FAILED]");
retour = -1;
}
else
System.out.println("TEST 6 Recherche ....................................................[OK]");
if (!dico.containsKey("Platon")) {
System.out.println("Erreur : L'élément devrait se trouver dans le dictionnaire");
System.out.println("TEST 6 Insertion ....................................................[FAILED]");
retour = -1;
}
else
System.out.println("TEST 6 Insertion ....................................................[OK]");
//TEST N°7:
//Insertion : TN*D1*END*EI
//Recherche : TN*D1*ENT
System.out.println("\nTEST N°7:");
System.out.println("Insertion : Essai d'insertion d'un élément dans un dictionnaire \nde taille n\nLe dictionnaire contient 1 élément, l'élément à insérer est inconnu");
System.out.println("Recherche : Essai de recherche d'un élément dans un dictionnaire \nde taille n\nLe dictionnaire contient 1 élément");
if (dico.get("Euclide") != null) {
System.out.println("Erreur : L'élément n'aurait pas du être trouvé");
System.out.println("TEST 7 Recherche ....................................................[FAILED]");
retour = -1;
}
else
System.out.println("TEST 7 Recherche ....................................................[OK]");
dico.put("Euclide", "Mathématicien grec");
if (!dico.containsKey("Euclide")) {
System.out.println("Erreur : L'élément n'a pas été inséré");
System.out.println("TEST 7 Insertion ....................................................[FAILED]");
retour = -1;
}
else {
boolean drapo = true;
if (dico.tailleTab != 4) {
System.out.println("Erreur : La taille du dictionnaire est incorrecte");
System.out.println("TEST 7 Insertion ....................................................[FAILED]");
retour = -1;
drapo = false;
}
if (dico.size() != 2) {
System.out.println("Erreur : Le nombre d'éléments est incorrect");
System.out.println("TEST 7 Insertion ....................................................[FAILED]");
retour = -1;
drapo = false;
}
if (drapo)
System.out.println("TEST 7 Insertion ....................................................[OK]");
}
//TEST N°8:
//Insertion : TN*DN4/3*ED*ENI
//Recherche : TN*DN4/3*ET
System.out.println("\nTEST N°8:");
System.out.println("Insertion : Essai d'insertion d'un élément dans un dictionnaire \nde taille n\nLe dictionnaire contient n éléments, l'élément à insérer est connu");
System.out.println("Recherche : Essai de recherche d'un élément dans un dictionnaire \nde taille n\nLe dictionnaire contient n éléments\nL'élément recherché est connu");
dico.put("Aristote", "Philosophe grec");
dico.put("Archimède", "Savant grec");
if (dico.get("Archimède") == null) {
System.out.println("Erreur : L'élément aurait du être trouvé");
System.out.println("TEST 8 Recherche ....................................................[FAILED]");
retour = -1;
}
if (!dico.containsKey("Aristote")) {
System.out.println("Erreur : L'élément devrait se trouver dans le dictionnaire");
System.out.println("TEST 8 Insertion ....................................................[FAILED]");
retour = -1;
}
else {
boolean drapo = true;
if (dico.tailleTab != 5) {
System.out.println("Erreur : La taille du dictionnaire est incorrecte");
System.out.println("TEST 8 Insertion ....................................................[FAILED]");
retour = -1;
drapo = false;
}
if (dico.size() != 4) {
System.out.println("Erreur : Le nombre d'éléments est incorrect");
System.out.println("TEST 8 Insertion ....................................................[FAILED]");
retour = -1;
drapo = false;
}
if (drapo)
System.out.println("TEST 8 Insertion ....................................................[OK]");
}
//TEST N°9:
//Insertion : TN*DN*END*EI
//Recherche : TN*DN*ENT
System.out.println("\nTEST N°9:");
System.out.println("Insertion : Essai d'insertion d'un élément dans un dictionnaire \nde taille n\nLe dictionnaire contient n éléments, l'élément à insérer est inconnu");
System.out.println("Recherche : Essai de recherche d'un élément dans un dictionnaire \nde taille n\nLe dictionnaire contient n éléments");
if (dico.get("Thalès") != null) {
System.out.println("Erreur : L'élément n'aurait pas du être trouvé");
System.out.println("TEST 9 Recherche ....................................................[FAILED]");
retour = -1;
}
else
System.out.println("TEST 9 Recherche ....................................................[OK]");
dico.put("Thalès", "Mathématicien grec");
if (!dico.containsKey("Thalès")) {
System.out.println("Erreur : L'élément n'a pas été inséré");
System.out.println("TEST 9 Insertion ....................................................[FAILED]");
retour = -1;
}
else {
boolean drapo = true;
if (dico.tailleTab != 7) {
System.out.println("Erreur : La taille du dictionnaire est incorrecte");
System.out.println("TEST 9 Insertion ....................................................[FAILED]");
retour = -1;
drapo = false;
}
if (dico.size() != 5) {
System.out.println("Erreur : Le nombre d'éléments est incorrect");
System.out.println("TEST 9 Insertion ....................................................[FAILED]");
retour = -1;
drapo = false;
}
if (drapo)
System.out.println("TEST 9 Insertion ....................................................[OK]");
}
return retour;
}
}