INF3105 — Structure de données et algorithmes
Automne 2016
wget http://ericbeaudry.ca/INF3105/lab9/lab9.zip unzip lab9.zip
Remplacez le fichier arbreavl.h par votre dernière version réalisée au Lab6.
Il est important de compléter le Lab6 avant d'amorcer le Lab9.
g++ -o test_arbremap test_arbremap.cpp.
Pour le TP2, il est utile d'avoir un itérateur d'ArbreMap, soit une classe ArbreMap<K,V>::Iterateur, afin d'itérer sur les entrées, des paires (clé,valeur), d'un dictionnaire de type ArbreMap.
La représentation d'un ArbreMap<K,V>::Iterateur est tout simplement un autre itérateur de type ArbreAVL<Entree>::Iterateur. La déclaration d'un itérateur devrait ressembler à cela.
class ArbreMap{
  // ...
  public:
    class Iterateur {
      public:
        Iterateur(const ArbreMap& a) : iter(a.entrees.debut()) {}
        Iterateur(typename ArbreAVL<Entree>::Iterateur i) : iter(i) {}
        operator bool() const;
        bool operator!() const;
        
        Iterateur& operator++();
        Iterateur operator++(int);
        const K& cle() const;
        const V& valeur() const; // ?? constant ou non ??
      private:
        typename ArbreAVL<Entree>::Iterateur iter;
    };
    // ...
    Iterateur debut() const;
    Iterateur fin() const;
    Iterateur rechercher(const K& cle) const;
    Iterateur rechercherEgalOuSuivant(const K& cle) const;
    Iterateur rechercherEgalOuPrecedent(const K& cle) const;
};
Il ne faut pas perdre de vue qu'on peut utiliser des itérateurs d'ArbreMap sur des dictionnaires constants ou non constants. Voici deux cas d'utilisation.
Cas #1 : ArbreMap constant :
    void fonction(const ArbreMap<string, int>& dictionnaire){
        ArbreMap<string, int>::Iterateur iter = dictionnaire.debut();
        const string& cle = iter.cle();
        const int& v = iter.valeur();
        ...
    }
Cas #2 : ArbreMap non constant :
    void fonction(ArbreMap<string, int>& dictionnaire){
        ArbreMap<string, int>::Iterateur iter = dictionnaire.debut();
        const string& cle = iter.cle();
        int& v = iter.valeur();
        v++;
        ...
    }
Il y a plusieurs façons de bien gérer les const. En voici deux :
L'option B est plus simple à implémenter. L'option A peut être plus conviviale pour l'utilisateur. À vous de choisir!
Enfin, décommentez les fonctions test3() et test4() dans test_arbremap.cpp et les appels de ces fonctions dans main().