^ Chapitre précédent ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ Chapitre suivant ^
====== Gérer des intervalles de valeurs ======
En mathématiques, un [[https://fr.wikipedia.org/wiki/Intervalle_(math%C3%A9matiques)|intervalle]] est l'ensemble des variables comprises entre deux valeurs. Par exemple, l'intervalle des entiers [1, 5[ (fermé à gauche et ouvert à droite) correspond aux valeurs 1, 2, 3, 4.
Le but de ces exercices va être d'écrire une représentation d'ensemble d'intervalles. Par exemple l'ensemble [0, 5[ U [10, 15[ correspond aux valeurs 0, 1, 2, 3, 4, 10, 11, 12, 13, 14.
Note : par symétrie avec les conteneurs standards, nous allons travailler sur des intervalles fermés à gauche et ouverts à droite.
En particulier, il faudra pouvoir gérer les unions et intersections d'intervalles :
* [0, 5[ U [2, 7[ = [0, 7[
* [0, 5[ I [2, 7[ = [2, 5[
===== Intervalle simple =====
**Première version**
Écrire une classe ''Interval_1'' permettant de gérer un intervalle simple d'entiers (''int'').
Construction et affectation
* construction à partir de deux valeurs ;
* assertion que les deux valeurs sont ordonnées ;
* sémantique de valeur : copiable, déplaçable (move).
Opérations de base
* intersection d'intervalle ;
* tester si une valeur appartient à un intervalle.
class Interval_1 {
...
private:
int low_value{};
int hight_value{};
};
**Seconde version**
Idem, avec template au lieu de ''int''.
template
class Interval_1_bis {
...
private:
T low_value{};
T hight_value{};
};
===== Intervalle composé =====
**Première version**
Idem, écrire une classe ''Interval_2'', mais ajout de l'union d'intervalles. Il n'est plus possible de conserver uniquement deux valeurs correspondant aux bornes.
Utiliser un vector pouvant recevoir plusieurs ''Interval_1'' défini précédemment. Il faut en particulier s'assurer de la cohérence et la simplification des données (l'union de deux intervalles peut produire deux intervalles ou un seul).
class Interval_2 {
...
private:
std::vector m_intervals{};
};
**Seconde version**
Utiliser un conteneur associatif (std::set) pour trier les intervalles. Note : deux intervalles disjoints sont ordonnables, deux intervalles non disjoints doivent être fusionnés pour former un seul intervalle.
class Interval_2_bis {
...
private:
std::set m_intervals{};
};
===== Ensemble de valeurs =====
**Première version**
Écrire une classe ''Interval_3'', en changeant de représentation interne. Au lieu de conserver des paires de valeurs pour représenter des intervalles, utiliser un tableau de valeurs avec l'état courant.
* l'intervalle [-inf, inf[ sera représenté en interne par un tableau vide ;
* l'intervalle [0, inf[ sera représenté en interne par la valeur {0, true} ;
* l'intervalle [0, 1[ sera représenté en interne par les valeurs {{0, true}, {1, false}} ;
* l'ensemble [0, 1[ U [2, 3[ sera représenté en interne par les valeurs {{0, true}, {1, false}, {2, true}, {3, false}}.
class Interval_3 {
...
private:
std::vector> m_intervals{};
};
**Deuxième version**
Idem, mais utiliser d'autres types que ''bool''. Par exemple avec ''char'' :
interval i; // [-inf, +inf[ = ''
i[0] = 'A'; // [-inf, 0[ = '', [0, +inf[ = 'A'
i[10] = 'B'; // [-inf, 0[ = '', [0, 10[ = 'A', [10, +inf[ = 'B'
cout << i[5] << std::endl; // 'A'
Écrire la classe correspondante :
* sémantique de valeur ;
* ajout de valeurs ;
* union et intersection ;
* tester une valeur.
class Interval_3_bis {
...
private:
std::vector> m_intervals{};
};
**Deuxième version**
Idem, mais avec templates
template
class Interval_3_bis {
...
private:
std::vector> m_intervals{};
};
^ Chapitre précédent ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ Chapitre suivant ^